HDU 6395 矩陣快速冪
阿新 • • 發佈:2018-12-09
矩陣很好構造:
F: f(n) A: D C 1 B: f(n-1)
f(n-1) 1 0 0 f(n-2)
CC(常數) 0 0 CC 1
CC是在變化的,但有的一段區間內是保持不變的;
比如:10/6,10/7,10/8,10/9,10/10 它們的都是1
對於不變的可以用矩陣加速,我們知道最後一個相等的下標為:p/(p/i)
還要注意一些細節
程式碼:
#include <set> #include <cmath> #include <queue> #include <stack> #include <vector> #include <string> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> #include <functional> #define PI acos(-1) typedef long long ll; using namespace std; const ll INF = 0xffffffff; const ll mod=1e9+7; ll a,b,c,d,p,n; struct node { ll num[3][3]; }A; void init() { for(ll i=0;i<3;i++) for(ll j=0;j<3;j++) A.num[i][j]=0; A.num[0][0]=d;A.num[0][1]=c; A.num[1][0]=1;A.num[2][2]=1; } node mul(node AA,node BB) { node C; for(ll i=0;i<3;i++) { for(ll j=0;j<3;j++) { C.num[i][j]=0; for(ll k=0;k<3;k++) { C.num[i][j]+=AA.num[i][k]*BB.num[k][j]; C.num[i][j]%=mod; } } } return C; } node Pow(ll nn,ll T,node B) { init(); A.num[0][2]=T; while(nn>0) { if(nn&1)B=mul(A,B); A=mul(A,A); nn=nn>>1; } return B; } void solve() { ll x,i,last,nn; node B; B.num[0][0]=b; B.num[1][0]=a; B.num[2][0]=1; for(i=3;i<=n;i=last+1) { x=p/i; if(x==0)break; last=p/(p/i); nn=last-i+1; if(last>n)nn=n-i+1; B=Pow(nn,x,B); } nn=n-i+1; if(i<=n)B=Pow(nn,0,B); cout<<B.num[0][0]<<endl; } int main() { ll t; cin>>t; while(t--) { cin>>a>>b>>c>>d>>p>>n; if(n==1){cout<<a<<endl;continue;} if(n==2){cout<<b<<endl;continue;} solve(); } }