1. 程式人生 > >[BZOJ2432][Noi2011]兔農(數論+矩陣乘法)

[BZOJ2432][Noi2011]兔農(數論+矩陣乘法)

Address

洛谷P2020
BZOJ2432
LOJ#2442

Solution

顯然是斐波那契數列
但是遞推式加入了鬼畜的條件:
f [ i ] = f [

i 1 ] + f [ i 2
] [ f [ i 1 ] +
f [ i 2 ] 1 (   m o d   k ) ] f[i]=f[i-1]+f[i-2]-[f[i-1]+f[i-2]\equiv1(\bmod k)]
我們考慮對在模 k k 意義下的 f f 進行討論。
可以發現,當 i > 2 i>2 時,如果是滿足 f [ i 1 ] + f [ i 2 ] 1 (   m o d   k ) f[i-1]+f[i-2]\equiv1(\bmod k) 最小的 i i
那麼 f [ i ] = 0 f[i]=0 ,而:
f [ i + 1 ] = f [ i ] + f [ i 1 ] = f [ i 1 ] f[i+1]=f[i]+f[i-1]=f[i-1]
同樣地, f [ i + 2 ] = f [ i + 1 ] + f [ i ] = f [ i 1 ] f[i+2]=f[i+1]+f[i]=f[i-1]
於是接下去在沒有模 k k 1 1 的情況時,有 f [ i + x ] = f [ i 1 ] × F i b ( x ) f[i+x]=f[i-1]\times Fib(x)
F i b ( x ) Fib(x) 為斐波那契數列第 x x 項)
考慮如果存在最小 j > i j>i 滿足 f [ j 1 ] + f [ j 2 ] 1 (   m o d   k ) f[j-1]+f[j-2]\equiv1(\bmod k)
那麼有 f [ i 1 ] × F i b ( j i ) 1 (   m o d   k ) f[i-1]\times Fib(j-i)\equiv 1(\bmod k)
用 exgcd 求出 f [ i 1 ] f[i-1] 的逆元 f [ i 1 ] 1 f[i-1]^{-1} ,找到一個最小的 j > i j>i
滿足 F i b ( j i ) = f [ i 1 ] 1 Fib(j-i)=f[i-1]^{-1} ,則 f [ j 1 ] + f [ j 2 ] 1 (   m o d   k ) f[j-1]+f[j-2]\equiv1(\bmod k)
如果 f [ i 1 ] f[i-1] 的逆元不存在或者不存在 F i b ( j i ) = f [ i 1 ] 1 Fib(j-i)=f[i-1]^{-1} ,則在 i i 之後不會出現模 k k 1 1 的情況。
又由於 F i b Fib k k 的餘數的最小正週期為 O ( k ) O(k) ,所以考慮先求出最小正週期 r r ,然後預處理出 1 1 r + 1 r+1 F i b Fib
然後求出 F i b [ 1 r + 1 ] Fib[1\dots r+1] 的逆元 i n v [ 1 r + 1 ] inv[1\dots r+1]
定義 F i b x Fib_x 為:
F i b x ( 1 ) = F i b x ( 2 ) = x Fib_x(1)=Fib_x(2)=x
F i b x ( n ) = F i b x ( n 1 ) + F i b x ( n 2 ) , n > 2 Fib_x(n)=Fib_x(n-1)+Fib_x(n-2),n>2