不好意思我是傻逼。。一不小心把後面的刪完了。。日後再補。。吐血,一下午寫的
原題:
題目描述
Fish 是一條生活在海里的魚,有一天他很無聊,就開始數數玩。他數數玩的具體規則是:
確定數數的進制B
確定一個數數的區間[L, R]
對於[L, R] 間的每一個數,把該數視爲一個字符串,列出該字符串的每一個(連續的)子串對應的B進制數的值。
對所有列出的數求和。現在Fish 數了一遍數,但是不確定自己的結果是否正確了。由於[L, R] 較大,他沒有多餘精力去驗證是否正確,你能寫一個程序來幫他驗證嗎?
輸入輸出格式
輸入格式:輸入包含三行。
第一行僅有一個數B,表示數數的進制。
第二行有N +1 個數,第一個數爲N,表示數L 在B 進制下的長度爲N,接下里的N個數從高位到低位的表示數L 的具體每一位。
第三行有M+ 1 個數,第一個數爲M,表示數R 在B 進制下的長度爲M,接下里的M個數從高位到低位的表示數R 的具體每一位。
輸出格式:輸出僅一行,即按照Fish 數數規則的結果,結果用10 進製表示,由於該數可能很大,輸出該數模上20130427的模數。
輸入輸出樣例
說明
【樣例解釋】
[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,
[