Sequence
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1186 Accepted Submission(s): 433
Problem Description
Let us define a sequence as below
Your job is simple, for each task, you should output Fn module 109+7.
⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊Pn⌋
Your job is simple, for each task, you should output Fn module 109+7.
Input
The first line has only one integer T, indicates the number of tasks.
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤T≤200≤A,B,C,D≤1091≤P,n≤109
Then, for the next T lines, each line consists of 6 integers, A , B, C, D, P, n.
1≤T≤200≤A,B,C,D≤1091≤P,n≤109
Sample Input
2
3 3 2 1 3 5
3 2 2 2 1 4
Sample Output
36
24
Source
Recommend
矩阵快速幂,但是中间带着一个跟着N变化的值;一开始想直接硬构造出一个矩阵;发现行不通就和队友搞其他题了;
后来发现这P/n在每个sqrt(q)范围内都是一定的;所以可以试着查找p/n这个值最大到哪一项,然后分别快速幂;很神奇的就是为什么p/(p/i)就是这个p/i的最大项;到现在还不明白‘
我的矩阵
Fn D C p/i Fn-1
Fn-1 1 0 0 Fn-2
1 0 0 1 1
代码:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9+7; const int maxn=3e6+50; const ll inf=0x3f3f3f3f3f3f; ll a,b,c,d,p,n; ll k,kk; ll fun[100000005]; struct node{ ll a[3][3]; void init(){ memset(a,0,sizeof(a)); for(int i=0;i<3;i++){ a[i][i]=1; } } }; node mul(node a,node b) { node ans; for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ ans.a[i][j]=0; for(int k=0;k<3;k++){ ans.a[i][j]+=a.a[i][k]*b.a[k][j]; ans.a[i][j]%=mod; } } }return ans; } void output(node a){ for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ cout<<a.a[i][j]<<" "; }cout<<endl; } } node qpow(node a,ll n){ node ans; ans.init(); while(n){ if(n&1)ans=mul(ans,a); a=mul(a,a); n/=2; } return ans; } node ac; void init(ll d,ll c,ll x){ ac.a[0][0]=d;ac.a[0][1]=c;ac.a[0][2]=x; /*ac D C P/I */ ac.a[1][0]=1;ac.a[1][1]=0;ac.a[1][2]=0; /* 1 0 0 */ ac.a[2][0]=0;ac.a[2][1]=0;ac.a[2][2]=1; /* 0 0 1 */ } node anw; void init2(ll a,ll b){ anw.a[0][0]=b;anw.a[1][0]=a;anw.a[2][0]=1; /*fn*/ } /*fn-1*/ node init3(node one,node two){ /*1*/ node retu; retu.a[0][0]=(one.a[0][0]*two.a[0][0]+one.a[0][1]*two.a[1][0]+one.a[0][2]*two.a[2][0])%mod; retu.a[1][0]=(one.a[1][0]*two.a[0][0]+one.a[1][1]*two.a[1][0]+one.a[1][2]*two.a[2][0])%mod; retu.a[2][0]=(one.a[2][0]*two.a[0][0]+one.a[2][1]*two.a[1][0]+one.a[2][2]*two.a[2][0])%mod; return retu; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); int t; cin>>t; while(t--){ cin>>a>>b>>c>>d>>p>>n; k=p/n;kk=p%n; if(n==1){cout<<a<<endl;continue;} if(n==2){cout<<b<<endl;continue;} else{ init(d,c,1); init2(a,b); //output(ac); // output(anw); for(ll i=3;i<=n;){ if(p/i==0){ ll num=n-i+1; init(d,c,0); node mid=qpow(ac,num); anw=init3(mid,anw); break; } else{ ll k=min(n,p/(p/i));//num表示p/i这个值最大到哪一个 ll num=k-i+1; init(d,c,p/i); node mid=qpow(ac,num); anw=init3(mid,anw); i=k+1; } } cout<<anw.a[0][0]<<endl; } } return 0; }