題意:
given n (1 <= n <= 1018), you should solve for
g(g(g(n))) mod 109 + 7
where
g(n) = 3g(n - 1) + g(n - 2)
g(1) = 1
g(0) = 0
分析:
這個遞推關係可以用矩陣快速冪來解決,但是這個題的問題是mod很大,會爆long long 並且超時的。那麼這就需要一些特技了。
於是看到大家都用的迴圈節,但是網上對為什麼要這麼取迴圈節卻都模糊或者答非所問,大概都不太曉得,知道可以a提就可以了,或者是大神們覺得這些小兒科的東西不用提上來講。我的理解是這是乙個自變數與函式值之間的關係的一種利用吧,比如g(x)%mod, 隨著g(x)的增大,總有一天會大過mod,然後又被變成0,重新開始,所以g(x)是迴圈的,它的迴圈節是mod,那麼g(x)的變化是隨著x的變化而變化的,那麼g(x)迴圈,x 也會相應的有迴圈節(這是根據函式的性質來決定的,不是所有的函式都有迴圈節,起碼這種類似斐波那契數列的函式可以),也就是說當x到達乙個值n時,g(x)==mod,x大於n之後g(x)也大過mod,那麼n+1和之前的1效果是一樣的,所以x的迴圈節就是n. 在這個題中有多個迴圈節是因為函式的巢狀,那麼最外層求得的自變數的迴圈節mod1就是裡面巢狀函式的函式值的迴圈節,依次遞推,找到三個迴圈節。
#include
#include
#include
#include
#include
#include
using
namespace
std;
#define read freopen("q.in","r",stdin)
#define ll long long
ll mod ;
struct matri
void init()
};matri mul(matri a,matri b)}}
return res;
}matri exp(matri a,ll n)
return res;
}int main()
if(n==1)
mod=183120l;
matri res=exp(b,n-1);
n=res.mat[0][0];
if(n!=0 && n!=1)
if(n!=0 && n!=1)
cout
<0][0]<}
}
迴圈節 矩陣快速冪 HDU4291
迴圈節其實就可以看做取模,一般的1e9 7其實就是個迴圈節,只是大了點 切入正題 hdu4291 g x 很明顯的矩陣快速冪 本地直接暴力找迴圈節 ll a 0,b 1 for int i 2 i 一定要 開 long long 我沒開 long long 卡了乙個多小時嗚嗚嗚嗚嗚 三個g巢狀,就分...
矩陣快速冪 迴圈節 hdu4291
題意 given n 1 n 1018 you should solve for g g g n mod 109 7 where g n 3g n 1 g n 2 g 1 1 g 0 0 分析 這個遞推關係可以用矩陣快速冪來解決,但是這個題的問題是mod很大,會爆long long 並且超時的。那麼...
hdu 4291 矩陣冪 迴圈節
凡是取模的都有迴圈節 常數有,矩陣也有,並且矩陣的更奇妙 g g g n mod 10 9 7 最外層mod 1e9 7 能夠算出g g n 的迴圈節222222224。進而算出g n 的迴圈節183120ll。然後由內而外計算就可以 凝視掉的是求迴圈節的 pragma comment linker...