HDU - 6395:Sequence (分块+矩阵)
题面太丑了,就不复制了。
题意:F1=A; F2=B; Fn=D*Fn-1+C*Fn-2+P/i;求Fn。
思路:根据P/i的值划分区间,每个区间矩阵求。
带常数的矩阵:
#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int Mod=1e9+7; struct mat { int mp[3][3]; mat(){memset(mp,0,sizeof(mp)); } mat friend operator *(mat a,mat b) { mat res; rep(k,0,2) rep(i,0,2) rep(j,0,2) res.mp[i][j]=(res.mp[i][j]+((ll)a.mp[i][k]*b.mp[k][j]%Mod))%Mod; return res; } mat friend operator ^(mat a,int x) { mat res; rep(i,0,2) res.mp[i][i]=1; while(x){ if(x&1) res=res*a; a=a*a; x>>=1; }return res; } }; int main() { int T,N,A,B,C,D,P,fcy; scanf("%d",&T); while(T--){ scanf("%d%d%d%d%d%d",&A,&B,&C,&D,&P,&N); if(N==1) {printf("%d",A); continue;} if(N==2) {printf("%d",B); continue;} for(int i=3,r;i<=N;i=r+1){ int tmp=P/i; if(tmp==0) r=N; else r=min(P/(P/i),N); mat ans,base; ans.mp[0][0]=B;ans.mp[1][0]=A; ans.mp[2][0]=1; base.mp[0][0]=D; base.mp[0][1]=C; base.mp[0][2]=tmp; base.mp[1][0]=base.mp[2][2]=1; ans=(base^(r-i+1))*ans; if(r==N) fcy=ans.mp[0][0]; else B=ans.mp[0][0],A=ans.mp[1][0]; } printf("%d\n",fcy); } return 0; }
It is your time to fight!