Arc of Dream
题目传送-HDU4686
题意:
给定\(n\),\(a_0\),\(b_0\),\(ax\),\(ay\),\(bx\),\(by\)
定义:\(f(i)=a_n*b_n\)
\(a_n=a_{n-1}*ax+ay\)
\(b_n=b_{n-1}*bx+by\)
求\(f(n)\)
\(n,a,b,ax,ay,bx,by \le 2^{18}\)
所有运算在\(mod 1e9+7\)意义下
题解:
显然的矩阵快速幂。
以\(f\),\(a_nb_n\),\(a_n\),\(b_n\),\(a_x\),\(a_y\),\(b_x\),\(b_y\)构建转移关系即可
过程:
矩阵抄错,调了30min
代码:
const ll P=1e9+7;
const int LEN=10;
ll n;
ll ax,ay,a,bx,by,b;
struct MAT {
ll mat[LEN][LEN];
inline void print() {
for(int i=0;i<=7;i++) {
for(int j=0;j<=7;j++)
printf("%lld ",mat[i][j]);
puts("");
}
}
inline void Construct() {
mem(mat,0);
mat[0][0]=1;
mat[0][1]=1;
mat[1][1]=ax*bx%P;
mat[1][2]=ax*by%P;
mat[1][3]=ay*bx%P;
mat[1][5]=by;
mat[2][2]=ax;
mat[2][5]=1;
mat[3][3]=bx;
mat[3][7]=1;
for(int i=4;i<=7;i++) mat[i][i]=1;
}
inline void Init() {
mat[0][0]=0;
mat[1][0]=a*b%P;
mat[2][0]=a;
mat[3][0]=b;
mat[4][0]=ax;
mat[5][0]=ay;
mat[6][0]=bx;
mat[7][0]=by;
}
inline MAT operator * (const MAT &b)const {
MAT c; mem(c.mat,0);
for(int i=0;i<=7;i++)
for(int j=0;j<=7;j++)
for(int k=0;k<=7;k++) {
c.mat[i][j]+=mat[i][k]*b.mat[k][j]%P;
if(c.mat[i][j]>=P) c.mat[i][j]-=P;
}
return c;
}
}trans,start,unit;
inline MAT Pow(MAT x,ll y) {MAT ret=unit; for(;y;y>>=1,x=x*x) if(y&1) ret=ret*x; return ret;}
signed main() {
for(int i=0;i<=7;i++) unit.mat[i][i]=1;
while(scanf("%lld",&n)!=EOF) {
read(a); read(ax); read(ay);
read(b); read(bx); read(by);
trans.Construct(); start.Init();
trans=Pow(trans,n); //trans.print();
printf("%lld\n",(trans*start).mat[0][0]);
}
return 0;
}
/*
1
1 2 3
4 5 6
2
1 2 3
4 5 6
3
1 2 3
4 5 6
*/
用时:1h