[SCOI2013] 數數 比較複雜的數位DP

不好意思我是傻逼。。一不小心把後面的刪完了。。日後再補。。吐血,一下午寫的


原題:

題目描述

Fish 是一條生活在海里的魚,有一天他很無聊,就開始數數玩。他數數玩的具體規則是:

  1. 確定數數的進制B

  2. 確定一個數數的區間[L, R]

  3. 對於[L, R] 間的每一個數,把該數視爲一個字符串,列出該字符串的每一個(連續的)子串對應的B進制數的值。

  4. 對所有列出的數求和。現在Fish 數了一遍數,但是不確定自己的結果是否正確了。由於[L, R] 較大,他沒有多餘精力去驗證是否正確,你能寫一個程序來幫他驗證嗎?

輸入輸出格式

輸入格式:

輸入包含三行。

第一行僅有一個數B,表示數數的進制。

第二行有N +1 個數,第一個數爲N,表示數L 在B 進制下的長度爲N,接下里的N個數從高位到低位的表示數L 的具體每一位。

第三行有M+ 1 個數,第一個數爲M,表示數R 在B 進制下的長度爲M,接下里的M個數從高位到低位的表示數R 的具體每一位。

輸出格式:

輸出僅一行,即按照Fish 數數規則的結果,結果用10 進製表示,由於該數可能很大,輸出該數模上20130427的模數。

輸入輸出樣例

輸入樣例#1: 複製
10
3 1 0 3
3 1 0 3
輸出樣例#1: 複製
120

說明

【樣例解釋】

[103, 103] 之間僅有數103,該數的所有子串包括1, 10, 103, 0, 03, 3,其和爲120。

【數據範圍與約定】

20% 數據,0 <= R <= L <= 10^5。

50% 數據,2 <= B <= 1000,1 <= N,M <= 1000。

100% 數據,2 <= B <= 10^5,1 <= N,M <= 10^5。

————————————————————————————分割線————————————————————————————

題解:

    還是按基本的數位DP的思路來,要計算[L, R]的值,就計算 [1, R] - [1, L-1] 。那麼我們這裏計算1到x按照fish的規則計算出來的結果。

    先考慮一個問題,如果要計算出一個數 432 按照fish的規則求和的答案,我們設f[i]表示給定的數字 x(432) 前i位的計算結果,顯然對於432這個數有f[1] = 4,f[2] = 4 + 3 + 43。我們可以看到,若要通過f[i]計算f[i+1],不含第i+1位數字的子串所得到的答案就是f[i],f[i+1]比f[i]多出來的部分都是由包含第i+1位的字串(也就是所以的後綴)所貢獻的。那麼我們可以令suf[i]表示前i數位的所有後綴的和,就可以得到f[i+1] = f[i] +suf[i+1]。下面就需要計算suf[i]這個數組,這也是這個題目的核心所在。

    直接給出b進制下suf[i]的遞推公式:suf[i+1] = suf[i] * b + a[i+1] * (i + 1)。 直觀地舉例說明一下:432的後綴和爲432 + 32 + 2,可以發現43+3是43的後綴和,也就是suf[2],他們在suf[3]中的貢獻是在suf[2]中貢獻的10倍,也就是suf[i] * b,同時可以看到a[i+1](也就是2)出現了3次,此時的3就是i+1,所以就能夠得出上面哪個遞推公式。

    接下來我們將 分別計算 前i位的後綴和 以及 第i+1位數字 在第i+1位的後綴和中的貢獻 ,這個思路擴展一下。還是以432舉例,我們設DP[i][0]表示前i位數字不涉及到邊界的答案。進一步解釋就是,DP[2][0]表示的就是[0, 42]這個區間的答案,DP[3][0]就是[0, 431]區間的答案。然後設DP[i][1]表示前i位數字邊界的答案,也就是DP[2][1]表示的就是43這一個數的答案。

    可以發現對於432來說,DP[1][0] = 1 + 2 + 3 = 6,DP[1][1] = 4,那麼DP[2][0]怎麼計算呢?[0, 42]這個區間的答案,先考慮[0, 39]區間,先考慮DP[1][0]對答案的貢獻,比如30,31,32,33,...,39,它們不包括第2位的子串都是隻有3一個字符,與DP[1][0]中的3是一樣的,但是出現了10次。也就是說不涉及到邊界(4)的情況下,前1位的每一個子串(1,2,3),都會在前2位中出現10次。同樣的,在不涉及到邊界(43)的情況下,前2位的每一個子串(比如42,4,2,41,4,1,40,4,0,39,3,9。。。)都會在前3位中出現10次,比如42,4,2會在420,421,422,423,...,429中一共出現10次。如果考慮邊界,也就是43的43,4,3,只會在430,431,出現2次,也就是a[3]次(沒有432是因爲此時我們考慮的是不涉及邊界432的情況)。從公式上來說就是DP[i][0]與DP[i][1]對DP[i+1][0]的貢獻是DP[i][0] * b + DP[i][1] * a[i+1]

    再考慮第i+1位數的出現對答案的貢獻。首先第i+1位數的出現就導致了新的後綴的產生,同樣地先考慮[0, 39]區間,對於任意一個數比如34,它的後綴就是34 + 4,

[




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章