小 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題解:
這道題如果不是要考慮每一次乘上的數是10的幾次方的話,那便是裸的矩陣快速冪,但是加上的話也無非就是多分幾種情況討論罷了。
首先看遞推式:f[i]=f[i-1]*10^k+i(可以看出只要對k討論)
然後寫出兩個矩陣:,,}和,,};
快速冪即可。
**如下:(注意每次迴圈的分類討論)
#include#include#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
typedef
long
long
lol;
lol n,m,now,pre;
struct
matrix
matrix(lol b[
3][3])
friend matrix
operator * (const matrix a,const
matrix b)
}s,t;
lol gi()
while(i>='
0'&&i<='9')
return ans*f;
}int
main()
,,};
s=matrix(s);
for(k=10;now10
) ,,};
t=matrix(t);
pre=min(k-1,n)-now;
while
(pre)
now=min(k-1
,n);
}printf(
"%lld\n
",s.a[0][0
]);
return0;
}
HNOI2011 數學作業
hnoi2011 數學作業 小 c 數學成績優異,於是老師給小 c 留了一道非常難的數學作業題 給定正整數 n 和 m 要求計算concatenate 1.n mod m 的值,其中 concatenate 1.n 是將所有正整數 1,2,n順序連線起來得到的數。例如,n 13,concatenat...
HNOI2011 數學作業
我又對著跑出正解的程式調了好久 怕不是眼瞎了 這就是個分段矩陣,我們很容易就得到了遞推式 f i f i 1 10 k i 其中 k log i 於是就是分段矩陣 矩陣 之後就是 了,沒有加快速乘wa了好久 cpp include include include define re register...
HNOI2011 數學作業
時間限制 1 s 記憶體限制 128 mb solution 用矩陣乘。在向後插入數時,相當於把原答案乘10的多少次方再加上這個數,所以我們可以導成矩陣。a矩陣 b矩陣 ans 10 j 1 0 i 0 1 1 1 0 0 1 b矩陣第一行是把ans 10 j i,第二行是讓i加1,第三行是保持a ...