數字統計小結

2021-05-23 15:39:31 字數 2876 閱讀 6281

「在資訊學競賽中,有這樣一類問題:求給定區間中,滿足給定條件的某個d 進製數或此類數的數量。所求的限定條件往往與數字有關,例如數字之和、指定數碼個數、數的大小順序分組等等。題目給定的區間往往很大,無法採用樸素的方法求解。此時,我們就需要利用數字的性質, 設計log(n)級別複雜度的演算法。 解決這類問題最基本的思想就是 「逐位確定」的方法。下面就讓我們通過幾道例題來具體了解一下這類問題及其思考方法。」——09集訓隊**《**數字類統計問題》by 劉聰

以前碰到過一些數字統計的題目,往往這類題目比較讓人惱火,做這類題的時候總是有一種力不從心的感覺,如果設計出來的演算法不漂亮那將意味著有眾多的細節需要一一特判之,比如去年的zjoi就有一道統計區間[l,r]中的數的每一位上0~9出現了多少次,結果這道題我整整做了兩個小時才把思路理順清楚。

這篇**向我介紹了一種非常形象的的思考及演算法方向,那就是數形結合。數字往往好深入分析但是太過於抽象,形則直觀明了但是難以究其根源,很好的結合兩者將會使得思考複雜度大大降低。

這篇**一共介紹了5到例題,ly還在poj上也找了一道數字統計題,至今還剩**中的最後一題沒有ac==。

1.amount of degrees (ural 1057)

題目大意:

求給定區間[x,y]中滿足下列條件的整數個數:這個數恰好等於k 個互不相等的 b的整

數次冪之和。例如,設x=15,y=20,k=2,b=2,則有且僅有下列三個數滿足題意:

17 = 10001

18 = 10010

20 = 10100

輸入:第一行包含兩個整數x 和 y。接下來兩行包含整數 k 和 b。

輸出:只包含乙個整數,表示滿足條件的數的個數。

資料規模:1 ≤ x ≤ y ≤ 231−1,1 ≤ k ≤ 20,  2 ≤ b ≤ 10。

分析:對於b>2的所有詢問都可以轉化成b=2,由淺入深的先考慮b=2的情況。

因為滿足區間減法,所以問題就轉化為統計[0,n]中的2進製數中1的個數為k的數的個數。

再簡單一點,如果n是2x-1的話答案是什麼?就是c(k,x)。

那麼能不能把[0,n]拆成若干個2x-1呢?可以的,如果我們把這裡面的數字看成一顆2叉樹,那麼這顆二叉樹肯定是由不超過logn個滿二叉樹構成的,所以我們可以把乙個問題拆分成logn個問題分別求解。

2.sorted bit sequence (spoj 1182)

題目大意

求給定區間[l,r]中第k大的數,兩個數的大小關係被定義為:對應的二進位制數中的1的個數為第一關鍵字,大小為第二關鍵字。

分析:首先直接列舉第k大的數的1的個數,問題轉化為求區間[l,r]中1的個數為x的數的個數,見第一題。

列舉出第k大的數的一的個數之後,在二分答案即可,同第一題。

3.apocalypse someday(poj3208)

題目大意

求第k大的包含666的數字

分析:依然是考慮逐位統計,預處理出f[i,j]表示還有i位沒有確定,之前有連續j個6的數有多少個,列舉每一位即可。

4.sequence (spoj 2319)

題目大意

給定所有k 位二進位制數:0,1,…,2k-1。你需要將它們分成恰好 m組,每組都是原序列中連續的一些數。設si(1 ≤ i ≤ m)表示第 i組中所有數的二進位制表示中 1 的個數,s等於所有si中的最大值。你的任務是令s最小。

資料規模:1 ≤ k ≤ 100, 1 ≤ m ≤ 100, m ≤ 2k。

分析最大值最小,很明顯的二分。

首先二分答案,然後貪心的求出最多可以分為幾組。

剩下的問題就是怎麼樣貪心了,我們可以每次選乙個點為起點然後再找到乙個最大的終點使得所有數1的個數≤s。

5.tickets (sgu 390)

題目大意:

有一位售票員給乘客售票。對於每位乘客,他會賣出多張連續的票,直到已賣出的票的編號的數字之和不小於給定的正數k。 然後他會按照相同的規則給下一位乘客售票。 初始時,售票員持有的票的編號是從l到r的連續整數。 請你求出, 售票員可以售票給多少位乘客。

輸入:三個整數l,r和k。

輸出:輸出乙個整數,表示問題的答案。

資料規模:1 ≤ l ≤ r ≤ 1018,1 ≤ k ≤ 1000。

分析本題與上題有些類似,也是對區間內的整數進行連續的分組。與上題不同的是,本題中k 的值較小,也就表示分組數量非常巨大,不可能求出每乙個分組。 讓我們同之前一樣,從特殊情況開始考慮。假設給定的區間是[1..10h-1](也就是一棵完整的高度為h的完全十叉樹) ,考慮如何由子問題組合出原問題。這裡我們遇到的問題是,兩棵子樹間的「合併」較難處理:前一棵子樹的最後乙個區間未必是滿的。亦即,一棵子樹的頭幾個元素會併入前一棵子樹最後的分組當中。為了解決這個問題,我們引入一維,記錄每棵子樹之前有多少空間。因此就得到了下面的遞推演算法:

設f[h,sum,rem]表示對於高度為h的完全十叉樹,在這個區間內的每個數需要累加的數字和為sum,在這個區間之前有rem的空間,所能得出的分組數量。f的返回值需要記錄兩個數:f[h,sum,rem].a記錄分組數量,f[h,sum,rem].b 記錄其最後乙個小組剩餘的空間,以便於與下乙個子樹合併。f可由其十個子樹推出:

for i:=0 to 9 do f[h,sum,rem]:=merge(f[h,sum,rem],f[h-1,sum+i,f[h,sum,rem].b]);

其中,merge函式表示合併兩個記錄,它的偽**是:

function merge(x,y);

x.a:=x.a+y.a;

x.b:=y.b; 

return x;

我們首先求出l和r的最近公共祖先,然後從 l所在的葉子向上走,每走一步就計算所有右側的兄**樹 。走到 lca的下一層後,再向右走到r的祖先。 然後向下走到r所在葉子, 計算途徑的左側兄**樹。

code2.

3. 4.

5.

數字DP 數字統計

題目 給定兩個正整數a和b,求在 a,b 中的所有整數中,每個數碼 digit 各出現了多少次。數字dp 1 分情況,逐位討論。2 模型 計算在 l,r 中有多少個數滿足條件。3 套路 將問題轉化為 1,r 1,l 1 只需回答 1,x 的詢問即可。思路1.算出 1,x 1 按位拆分,為後面做鋪墊 ...

數字DP小結

download.csdn.net detail u012959992 8892265 一般是求小於等於數字n的某些特徵數字個數,或者是區間 l,r 的之間的某些特徵數字個數,後者一般可以轉換成求差的方式來做。數字處理函式int f int num return dfs pos,s true dig...

數字dp小結

數字dp可不是對於數的每一位進行dp,而是指對於這個數的組成進行dp。對於數的每一位進行dp,只是數字dp的一類題目。題目描述 現在有兩個要求 這是乙個 n n 106 n n leq 10 6 n n 10 6 位的數 不含前導零 相鄰的兩位的差值大於等於 p p 9 p p leq 9 p p ...