bzoj2326 CodeVS2314 數學作業

2021-07-09 23:27:15 字數 924 閱讀 9350

題意:求123456789101112……n對m取模的結果。n<=10^18,m<=10^9。

記f(i)=concatenate(1...i),則有f(i+1)=f(i)*10^k+i+1,其中k為i+1的位數。

首先,對於連續的一段遞推式,10^k的值是不變的,因此可以考慮分段進行矩陣乘法快速冪來優化遞推。

但是這裡下標i的值也參與了計算,

因此我們可以考慮維護乙個值使其總是等於下標,於是我們有:

[ f(i), i, 1 ] * [ base, 0, 0 ] = [ f(i+1), i+1, 1 ]

[ 1,        1, 0 ]

[ 1,        1, 1 ]

或[ f(i), i+1, 1 ] * [ base, 0, 0 ] = [ f(i+1), i+2, 1 ]

[ 1,        1, 0 ]

[ 0,        1, 1 ]

我寫的是後者。

**: #include

#include

#define rpt(i,l,r) for(i=l;i<=r;i++)

long long n,k;

int m;

struct matrix

}}a,b,c;

matrix operator *(matrix a,matrix b)

const matrix i=(matrix);

matrix operator ^(matrix a,long long x)

return res;

}int main();

b=(matrix);

k=1;

while(k<=n/10)

a=a*(b^(n-k+1));

printf("%d",a.v[0][0]);

}

BZOJ2326 數學作業

題目傳送門 設n的答案為f n 那麼很容易得到乙個遞推式 f n f n 1 10k n,其中k是n的位數。所以當k固定時,這個式子的轉移方式也是固定的。所以可以列舉每個k。而對於每乙個k,我們很容易得到乙個矩陣 10 k,1,1 0,1,1 0 1,1 對每乙個k,就可以快速計算答案。code i...

bzoj 2326 HNOI2011 數學作業

題目大意 給你n,m,求concatenate 1.n mod m的值 concatenate 1.n 代表把1到n連起來 比如n 13時 concatenate 1.n 就是12345678910111213 n 10 1 m 10 9 這題很水,對於n,將其分開,比如145,就分成1 9,10 ...

bzoj2326 HNOI2011 數學作業

一開始一直不理解矩陣乘法是什麼東西。現在有一點自己的想法。對於如f i 1 a f i b,可以構造乙個矩陣b,使矩陣a i 矩陣b 矩陣a i 1 然後利用矩陣快速冪加速。這道題對於不同的位數有不同的遞推式。設位數為k,f i 1 10 k f i i 1,可構造3 3的矩陣 10 k,1,1 0...