http://acm.hdu.edu.cn/showproblem.php?pid=4686
When you see n as a number less than 64-bit integer, you should have a feeling that this should be the fast power of the Tao Matrix in the ACM category.
Ai,bi's recursive topic has been given,
ai*bi=ax*bx* (ai-1*bi-1) +ax*by*ai-1+bx*ay*bi-1+ay*by
AoD (n) =aod (n-1) +aibi
Construction Vector i{aod (i-1), ai*bi,ai,bi,1}
Initial vector is i0={0,a0*b0,a0,b0,1}
Structural Matrix a{
1,0,0,0,0,
1,ax*bx,0,0,0,
0,ax*by,ax,0,0,
0,bx*ay,0,bx,0,
0,ay*by,ay,by,1,
}
Then i0* (A) ^n is the vector containing the result, at which point I[0] is the answer
Attention:
1. It is said to have n=0, direct output 0
Use of 2.long long
#include <cstdio> #include <cstring> #include <algorithm>using namespace Std;typedef long ll; CONST LL mod = 1e9+7;ll n,ao,bo,ax,bx,ay,by;void init (ll** ans,ll** base) {Fill (ans[0],ans[0]+5,0); Fill (base[0],base[0]+25,0); Ans[0][1]=ao*bo%mod; Ans[0][2]=ao; Ans[0][3]=bo; Ans[0][4]=1; Base[0][0]=1; Base[1][0]=1;base[1][1]=ax*bx%mod; Base[2][1]=ax*by%mod;base[2][2]=ax; BASE[3][1]=BX*AY%MOD;BASE[3][3]=BX; Base[4][1]=ay*by%mod;base[4][2]=ay;base[4][3]=by;base[4][4]=1;} void print (ll **t, int m,int r) {for (int. i=0;i<m;i++) {for (int j=0;j<r;j++) { printf ("%i64d", T[i][j]); } puts (""); }}void multi (ll** t,ll** b,ll * tmp,int m,int r,int s) {fill (tmp[0],tmp[0]+m*s,0); for (int i=0;i<m;i++) {for (int. j=0;j<s;j++) {for (int k=0;k<r;k++) { tmp[i][j]+= (T[i][k]*b[k][j])%mod; Tmp[i][j]%=mod; }}}}void Qpow (ll** ans,ll * * base,ll**tmp,ll time,int r,int m) {while (time>0) { if (time&1) {multi (ans,base,tmp,r,m,m); Copy (Tmp[0],tmp[0]+r*m,ans[0]); time--; } multi (BASE,BASE,TMP,M,M,M); Copy (Tmp[0],tmp[0]+m*m,base[0]); time>>=1; }}int Main () {ll * * ans = new ll*[1],**tmp=new ll*[5],** base =new ll*[5]; Ans[0]=new ll[5],tmp[0]=new ll[25],base[0]=new ll[25]; for (int i=1;i<5;i++) {tmp[i]=tmp[0]+5*i; Base[i]=base[0]+5*i; } while (scanf ("%i64d", &n) ==1) {scanf ("%i64d%i64d%i64d", &ao,&ax,&ay); Ao%=mod;ax%=mod;ay%=mod; scanf ("%i64d%i64d%i64d",&bo,&bx,&by); Bo%=mod;bx%=mod;by%=mod; if (n==0) puts ("0"); else {init (ans,base); Qpow (ans,base,tmp,n,1,5); printf ("%i64d\n", ans[0][0]); }} Delete Ans;delete base;delete tmp; return 0;}
HDU 4686 ARC of the Dream matrix fast power, linear congruence difficulty: 1