小 c 數學成績優異,於是老師給小 c 留了一道非常難的數學作業題:
給定正整數 n 和 m,要求計算 concatenate (1 .. n) mod m 的值,其中 concatenate (1 ..n)是將所有正整數 1, 2, …, n 順序連線起來得到的數。例如,n = 13, concatenate (1 .. n)=12345678910111213.小c 想了大半天終於意識到這是一道不可能手算出來的題目,於是他只好向你求助,希望你能編寫乙個程式幫他解決這個問題。
輸入格式:
從檔案input.txt中讀入資料,輸入檔案只有一行且為用空格隔開的兩個正整數n和m,其中30%的資料滿足1≤n≤1000000;100%的資料滿足1≤n≤1018且1≤m≤109.
輸出格式:
輸出檔案 output.txt 僅包含乙個非負整數,表示 concatenate (1 .. n) mod m 的值。
輸入樣例#1:
13 13輸出樣例#1:
4
題解:想想看,如果n範圍比較小時你會怎麼做?我們應該想到,比如說對於序列1234567,要取模的數是13,那麼我們會先讓1對13取模得到1,再讓12對13取模得到12,再讓123對13取模得到6,再讓64對13取模得到12,再讓125對13取模得到8,再讓86對13取模得到8,最後讓87對13取模得到9。這與1234567直接對13取模的值是相同的。其中的數學證明不再贅述。
於是我們可以得到遞推式,對於序列f(n),f(n)=f(n-1)×10^len(n)+n(其中len(n)表示n這個數字有幾位)。
由於n的範圍極大,我們考慮用矩陣快速冪轉移優化,構造矩陣如下:
f(n) 10^len(n) 1 1 f(n-1)
n = 0 1 1 × n-1
1 0 0 1 1
我們轉移時,根據1~9時len(i)相同,10~99時len(i)相同,100~999時len(i)相同劃分為不同的區塊進行轉移優化。
這個轉移思路是從whc大佬那裡獲得的,本蒟蒻還是太弱了。
接下來還是看**吧。
1 #include2 #include3 #include4view codeusing
namespace
std;
5const
int n=3;6
struct
node
9 }ans,p[20
];10
long
long
n,mod,now,t;
11 node operator *(node x,node y)
1220 node pow(node x,long
long
y)21
26long
long calc(long
long x,long
long
y)27
32int
main()
33
洛谷 P3216 HNOI2011 數學作業
最近學了矩陣,kzj大佬推薦了我這一道題目。乍一眼看上去,沒看出是矩陣,就隨便打了乙個暴力,30分。然後仔細分析了一波,發現蠻簡單的。結果全wa了,先看看下面的錯誤分析吧!首先,設f n 為最終答案,易得出 f n f n 1 10 n 然後魔改一下 f n f n 1 10 n 1 begin 1...
洛谷P3216 HNOI2011 數學作業
題目描述 小 c 數學成績優異,於是老師給小 c 留了一道非常難的數學作業題 給定正整數 n 和 m,要求計算 concatenate 1 n mod m 的值,其中 concatenate 1 n 是將所有正整數 1,2,n 順序連線起來得到的數。例如,n 13,concatenate 1 n 1...
洛谷 P3197 HNOI2008 越獄
來來來,日常水一篇 滑稽 監獄有連續編號為1 n的n個房間,每個房間關押乙個犯人,有m種宗教,每個犯人可能信仰其中一種。如果相鄰房間的犯人的宗教相同,就可能發生越獄,求有多少種狀態可能發生越獄 輸入格式 輸入兩個整數m,n.1 m 10 8,1 n 10 12 輸出格式 可能越獄的狀態數,模1000...