2438. 二的冪數組中查詢范圍內的乘積

2438. 二的冪數組中查詢范圍內的乘積

初始理解題目

首先,我們需要清楚地理解題目在說什么。題目給出一個正整數?n,要求我們構造一個數組?powers,這個數組滿足以下條件:

  1. 元素性質?:數組中的每個元素都是 2 的冪。即,每個元素可以表示為 2^k,其中 k 是非負整數(k ≥ 0)。
  2. ?和的條件?:這些 2 的冪的和等于給定的?n

  3. ?最少數目?:在所有滿足上述條件的數組中,powers應該包含最少數量的元素。

  4. 非遞減順序?:數組中的元素是按非遞減順序排列的,即對于任意 i < j,有?powers[i] ≤ powers[j]
  5. 唯一性?:在滿足上述所有條件的情況下,構造?powers的方法是唯一的。

任何正整數?n都可以表示為若干個不同的2的冪的和,這實際上就是?n的二進制表示。例如:

5 的二進制是 101,可以表示為?4+1=5。

6 的二進制是 110,可以表示為?4+2=6。

7 的二進制是 111,可以表示為?4+2+1=7

在這種表示中,每個2的冪最多出現一次,因為二進制每一位只能是0或1。這種表示方法已經使用了最少數量的2的冪(因為不能合并相同的冪次)。

然而,題目允許數組中的元素可以重復(因為是非遞減順序,可以連續相同),但要求最少數目。這意味著我們需要盡可能合并相同的2的冪。

我們需要解決兩個主要部分:

在前面的討論中,我們已經明確了?powers的構造方法:將?n的二進制表示中所有為?1的位對應的2的冪按從小到大的順序排列。例如:

構造?powers數組?:給定一個正整數?n,構造一個由2的冪組成的、非遞減的數組?powers,使得?powers中所有元素的和為?n,并且?powers中的元素數量盡可能少。這個數組是唯一的。

處理查詢?queries?:給定多個查詢?queries[i] = [lefti, righti],對于每個查詢,我們需要計算?powers數組中從索引?lefti到?righti(包含兩端)的所有元素的乘積,并將結果取余。

例如:

  • powers = [1, 4],查詢?[0, 1]→ 計算?1 * 4 = 4
  • powers = [2, 4],查詢?[0, 0]→ 計算?2

解決思路

構造?powers數組?:

  • 將?n轉換為二進制遍歷二進制的每一位,如果該位為?1,則將對應的2的冪加入?powers
  • 由于二進制是從低位到高位讀取的,而?powers需要是非遞減的,因此直接按從小到大的順序添加即可。

?預處理?powers的前綴積?:

  • 為了高效計算任意區間?[left, right]的乘積,可以預先計算?powers的前綴積數組?prefix。
  • prefix[0] = powers[0]
  • prefix[i] = prefix[i-1] * powers[i] % MOD(其中?MOD = 10^9 + 7)
  • 這樣,區間?[left, right]的乘積可以表示為?prefix[right] / prefix[left-1](如果?left > 0),或者?prefix[right](如果?left == 0)。
  • 由于模運算中除法等同于乘以逆元,因此需要預先計算?prefix的逆元組?inv_prefix。

處理查詢?:? ??

  • 對于每個查詢?[left, right]:
  • 如果?left == 0,則結果為?prefix[right]。
  • 否則,結果為?prefix[right] * inv_prefix[left-1] % MOD。
  • 由于?prefix和?inv_prefix已經預先計算,每個查詢可以在 O(1) 時間內完成
具體步驟
1.?構造?powers數組?:

初始化?powers = []。

????????power = 1(即?2的0次方)。

當?n > 0:

????????如果?n % 2 == 1,將?power加入?powers。

????????n = n // 2。

????????power = power * 2。

????????這樣得到的?powers已經是非遞減順序。

2.計算前綴積?prefix?:

初始化?prefix = [1] * len(powers)。

prefix[0] = powers[0] % MOD。

對于?i從?1到?len(powers)-1:

prefix[i] = (prefix[i-1] * powers[i]) % MOD。

3.計算逆元前綴積?inv_prefix?:

逆元的計算可以通過費馬小定理:inv(a) = pow(a, MOD-2, MOD)。

初始化?inv_prefix = [1] * len(powers)。

inv_prefix[-1] = pow(prefix[-1], MOD-2, MOD)。

對于?i從?len(powers)-2到?0:

inv_prefix[i] = (inv_prefix[i+1] * powers[i+1]) % MOD。

4.處理查詢?:

對于每個查詢?[left, right]:

????????如果?left == 0:

????????????????answer = prefix[right]。

????????否則:

????????????????answer = (prefix[right] * inv_prefix[left-1]) % MOD。

????????????????將?answer加入?answers。

示例驗證

?示例1?:

  • ?

    n = 5→?powers = [1, 4]

  • ?

    prefix = [1, 4](因為?1 % MOD = 1,?1 * 4 % MOD = 4)。

  • ?

    inv_prefix

    • ?

      inv_prefix[1] = pow(4, MOD-2, MOD)

    • ?

      inv_prefix[0] = (inv_prefix[1] * 4) % MOD

    假設?MOD = 10^9 + 7

    • ?

      pow(4, MOD-2, MOD)是?4的逆元,即?x滿足?4 * x ≡ 1 mod MOD

    • ?

      計算得?inv_4 = 250000002(因為?4 * 250000002 = 1000000008 ≡ 1 mod 1000000007)。

    • ?

      inv_prefix[1] = 250000002

    • ?

      inv_prefix[0] = (250000002 * 4) % MOD = 1

  • ?

    查詢?[0, 1]

    • ?

      left = 0→?answer = prefix[1] = 4

  • ?

    查詢?[1, 1]

    • ?

      left = 1→?answer = prefix[1] * inv_prefix[0] % MOD = 4 * 1 % MOD = 4

?示例2?:

  • ?

    n = 6→?powers = [2, 4]

  • ?

    prefix = [2, 8]

  • ?

    inv_prefix

    • ?

      inv_prefix[1] = pow(8, MOD-2, MOD)

      • ?

        inv_8 = 125000001(因為?8 * 125000001 = 1000000008 ≡ 1 mod 1000000007)。

    • ?

      inv_prefix[0] = (125000001 * 4) % MOD = 500000004(因為?125000001 * 4 = 500000004)。

  • ?

    查詢?[0, 1]

    • ?

      left = 0→?answer = prefix[1] = 8

  • ?

    查詢?[0, 0]

    • ?

      left = 0→?answer = prefix[0] = 2

邊界情況

  1. 1.

    ?n = 0?:

    • ?

      題目中?n是正整數,不考慮。

  2. 2.

    ?n = 1?:

    • ?

      powers = [1]

    • ?

      prefix = [1]

    • ?

      查詢?[0, 0]→?1

  3. 3.

    ?查詢的?left或?right超出?powers的索引范圍?:

    • ?

      題目中?queries是基于?powers的索引,假設輸入是合法的。

  4. 4.

    ?powers長度為1?:

    • ?

      所有查詢的?left和?right必須為?0

代碼實現

 

python

下載

復制

運行

MOD = 10**9 + 7def min_powers(n):powers = []power = 1while n > 0:if n % 2 == 1:powers.append(power)n = n // 2power = power * 2return powersdef solve(n, queries):powers = min_powers(n)m = len(powers)if m == 0:return [0] * len(queries)# Compute prefix productsprefix = [1] * mprefix[0] = powers[0] % MODfor i in range(1, m):prefix[i] = (prefix[i-1] * powers[i]) % MOD# Compute inverse prefix productsinv_prefix = [1] * minv_prefix[-1] = pow(prefix[-1], MOD-2, MOD)for i in range(m-2, -1, -1):inv_prefix[i] = (inv_prefix[i+1] * powers[i+1]) % MOD# Process queriesanswers = []for left, right in queries:if left == 0:res = prefix[right]else:res = (prefix[right] * inv_prefix[left-1]) % MODanswers.append(res)return answers

復雜度分析

  1. 1.

    ?構造?powers?:

    • ?

      時間:O(log n),因為每次?n除以2。

    • ?

      空間:O(log n),存儲?powers

  2. 2.

    ?計算前綴積和逆元前綴積?:

    • ?

      時間:O(m),其中?m是?powers的長度(最多 log n)。

    • ?

      空間:O(m),存儲?prefix和?inv_prefix

  3. 3.

    ?處理查詢?:

    • ?

      每個查詢 O(1),總時間 O(q),其中?q是查詢數量。

    • ?

      空間:O(q),存儲結果。

總時間復雜度:O(log n + q)。

總空間復雜度:O(log n + q)。

優化

注意到?inv_prefix的計算可以優化:

  • ?

    inv_prefix[i] = pow(prefix[i], MOD-2, MOD)

  • ?

    這樣可以直接計算每個?prefix[i]的逆元,而不需要遞推。

  • ?

    但遞推的方法在模運算中更高效,因為?pow(a, MOD-2, MOD)的時間是 O(log MOD) ≈ 30 次運算。

示例運行

?輸入?:

  • ?

    n = 5,?queries = [[0, 1], [1, 1]]

?步驟?:

  1. 1.

    powers = [1, 4]

  2. 2.

    prefix = [1, 4]

  3. 3.

    inv_prefix

    • ?

      inv_prefix[1] = pow(4, MOD-2, MOD) = 250000002

    • ?

      inv_prefix[0] = (250000002 * 4) % MOD = 1

  4. 4.

    查詢:

    • ?

      [0, 1]prefix[1] = 4

    • ?

      [1, 1]prefix[1] * inv_prefix[0] % MOD = 4 * 1 % MOD = 4

?輸出?:

[4, 4]

最終答案

對于給定的?n和?queries,按照上述方法構造?powers數組,并預處理前綴積和逆元前綴積,然后對每個查詢計算區間乘積并取余,最后返回所有查詢的結果。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92637.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92637.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92637.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【PyTorch學習筆記 - 01】 Tensors(張量)

最近項目需要優化一下目標檢測網絡&#xff0c;在這個過程中發現還是得增加對框架底層的掌握才可行。于是準備對pytorch的一些基本概念做一些再理解。參考PyTorch的wiki&#xff0c;對自己的學習過程做個記錄。 Tensors 是一種特殊的數據結構&#xff0c;與數組和矩陣非常相似…

【C/C++】(struct test*)0->b 講解

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 一、什么是結構體成員的偏移量&#xff1f; 二、為什么需要計算偏移量&#xff1f; 三、如何計算偏移量&#xff1f; 四、總結 一、什么是結構體成員的偏移量&#…

使用Pytest進行接口自動化測試(三)

&#xff08;一&#xff09;YAML 之前在項目中&#xff0c;我們也是用過YAML來做配置文件&#xff0c;他用于以人類可讀的形式存儲信息&#xff0c; 特點: 一種簡易的可讀語言&#xff0c;用于人和計算機交換數據 通常用來存儲配置信息 跟python類似&…

算法訓練營day46 647. 回文子串、516.最長回文子序列、動態規劃總結篇

今天是動態規劃的最后一篇內容了&#xff0c;本篇主要是針對回文字符串這種“與眾不同”的遞推規律來進行講解 647. 回文子串 統計并返回這個字符串中 回文子串 的數目 暴力解法 兩層for循環&#xff0c;遍歷區間起始位置和終止位置&#xff0c;然后還需要一層遍歷判斷這個區…

Qt界面優化

1.QSS在網頁前端開發領域中&#xff0c;CSS 是一個至關重要的部分&#xff0c;描述了一個網頁的 “樣式”&#xff0c;從而起到對網頁美化的作用。所謂樣式&#xff0c;包括不限于大小、位置、顏色、背景、間距、字體等等。網頁開發作為 GUI 的典型代表&#xff0c;也對于其他客…

week1+2+3

408 計組 1.基本組成2.數據的表示和運算定點數&#xff1a;把數字分為定點整數和定點小數分開存儲 浮點數&#xff1a;用科學計數法存儲 原碼 -全部取反-> 反碼 反碼 1->補碼 補碼 -符號位取反->移碼帶余除法&#xff1a;設x,m∈Z&#xff0c;m>0則存在唯一的整數q…

java8中javafx包缺少報錯

今天拉取一個jdk1.8的項目里面有一個代碼用到了javafx&#xff0c;這個我記得是jdk中的包&#xff0c;正常不應該報錯的。然后發現jdk中還真沒有&#xff0c;查了一下是因為版本問題。 Java 8 及之前&#xff1a;Oracle JDK 自帶 JavaFX&#xff0c;OpenJDK 通常不包含Java 9 …

day072-代碼檢查工具-Sonar與maven私服-Nexus

文章目錄0. 老男孩思想-選對池塘釣美人魚1. 代碼回滾方案2. SonarQube2.1 代碼檢查工具2.2 部署sonarqube2.2.1 軟件要求2.2.2 安裝軟件2.2.3 啟動sonar2.2.4 部署插件2.3 sonar檢查java代碼2.3.1 創建sona項目2.3.2 分析java代碼2.3.3 Jenkins結合sonar檢查代碼2.4 sonar檢查非…

【前端基礎】15、列表元素、表格元素、表單元素(注:極其粗略的記載。)

一、列表元素 1、什么是列表元素2、有序列表&#xff08;ol、li&#xff09; ol有序列表 直接子元素只能是li。 li列表中的每一項。3、無序列表&#xff08;ul、li&#xff09; ol無序列表 直接子元素只能是li。 li列表中的每一項。4、定義列表&#xff08;dl、dt、dd&#xff…

IRFBG30PBF Vishay威世MOSFET場效應管

IRFBG30PBF Vishay威世&#xff1a;超快MOSFET 場效應管一、產品定位IRFBG30PBF 是Vishay威世推出的600V/30A N溝道功率MOSFET&#xff0c;采用第五代TrenchFET技術&#xff0c;專為開關電源、電機驅動、新能源逆變器等高功率場景設計。以85mΩ超低導通電阻和超快反向恢復&…

【07-AGI的討論】

AI ANI&#xff1a;artificial narrow intelligence; 如 智能音箱&#xff1b;自動駕駛汽車&#xff0c;網絡搜索&#xff0c;其他用于專業特定事項的工具&#xff1b; AGI&#xff1a;artificial general intelligence; building AI systems that could do anything a typical…

[激光原理與應用-225]:機械 - 3D圖與2D圖各自的作用

在機械設計與加工領域&#xff0c;3D圖和2D圖是兩種核心的工程表達方式&#xff0c;它們在產品設計、制造、裝配及維護等環節中扮演不同角色&#xff0c;具有互補性。以下是它們各自的作用及具體應用場景的詳細解析&#xff1a;一、3D圖的作用1. 直觀展示產品全貌三維可視化&am…

【從零開始java學習|第一篇】java中的名詞概念(JDK、JVM、JRE等等)

目錄 一、核心運行環境三要素&#xff08;JVM/JRE/JDK&#xff09; 二、常用開發指令&#xff08;JDK 自帶工具&#xff09; 三、一些其他概念 四、總結核心邏輯鏈 要入門 Java&#xff0c;理解核心概念之間的關系是基礎。以下是 Java 中最核心的基礎概念、工具及相關名詞的…

UVa12345 Dynamic len(set(a[L:R]))

[TOC](UVa12345 Dynamic len(set(a[L:R]))) 題目鏈接 UVA - 12345 Dynamic len(set(a[L:R])) 題意 有編號從 0 到 n?1 的 n 個數&#xff0c;有兩種操作&#xff1a; Q L R 詢問編號 L 到編號 R?1 的數中有多少個不同的數字。M X Y 將編號為 X 的數字改為 Y。 你的任務就是…

[Ubuntu] VNC連接Linux云服務器 | 實現GNOME圖形化

將桌面環境修改為 GNOME 并通過 VNC 遠程訪問的步驟 & TightVNC 的安裝與配置說明&#xff1a;1. 安裝 GNOME 桌面環境 sudo apt update sudo apt install ubuntu-gnome-desktop -y2. 安裝 TightVNC 服務器 sudo apt install tightvncserver -y3. 初始化 VNC Server 并設置…

進程、網絡通信方法

一、進程間通信(IPC)方法 適用于同一臺主機上的進程間數據交換。 管道(Pipe) 匿名管道:單向通信,僅用于父子進程。 命名管道(FIFO):通過文件系統路徑訪問,支持無親緣關系進程。 消息隊列(Message Queue) 結構化消息(類型+數據),按類型讀取,支持異步通信。…

[激光原理與應用-241]:設計 - 266n皮秒深紫外激光器,哪些因素影響激光器紫外光的輸出功率?

一、短期穩定性266nm皮秒深紫外激光器紫外光輸出功率的穩定性受非線性晶體性能、光學系統設計、熱管理效果、重復頻率與脈沖能量匹配度、環境干擾控制等因素影響&#xff0c;具體分析如下&#xff1a;1. 非線性晶體性能晶體選擇與狀態&#xff1a;BBO&#xff08;偏硼酸鋇&…

Django配置sqllite之外的數據庫

當連接到其他數據庫后端時&#xff0c;如 MariaDB、MySQL、Oracle 或 PostgreSQL&#xff0c;將需要額外的連接參數。請參閱下面的 ENGINE 配置&#xff0c;了解如何指定其他數據庫類型。這個例子是針對 PostgreSQL&#xff1a; 在django項目的settings.py文件里&#xff0c;關…

銀河通用招人形機器人強化學習算法工程師了

人形強化學習算法工程師&#xff08;26屆&#xff09;&#xff08;崗位信息已通過jobleap.cn授權&#xff0c;可在csdn發布&#xff09;銀河通用機器人 北京收錄時間&#xff1a; 2025年08月11日職位描述1. 研發基于深度強化學習的足式機器人運動控制算法&#xff0c;提升機器…

使用MongoDB存儲和計算距離

一、MongoDB 計算距離的優勢 優勢說明原生地理空間索引支持 2dsphere 索引&#xff0c;高效處理地理坐標查詢&#xff08;毫秒級響應&#xff09;。內置地理計算函數提供 $near、$geoWithin、$geoNear 等操作符&#xff0c;無需手動實現復雜計算。高性能基于B樹索引優化&#…