1001:hdu4686 矩阵快速幂
这题一开始没有想到怎么构造矩阵,纠结了半天,最后ws搞出来了,思路还是蛮简单的。直接把ai*bi的递推式化简,然后看有哪些项,然后构造这些项,再多加一个求和的项。
还有注意一点就是,矩阵不能开太大,8*8的TLE了,5*5就行了。
代码:
#include<iostream> #include<cstdio> #include<vector> #include<string> #include<queue> #include<cstring> #define maxn 10005 #define INF 0xfffffff #define mem(a,b) memset(a,b,sizeof(a)) #define FOR(i,s,t) for(int i=s;i<=t;i++) #define ull unsigned long long #define ll __int64 using namespace std; ll Mod =1000000007; ll a0,b0,ax,ay,bx,by,n; struct Mat { int n,m; ll a[6][6]; }; Mat A0,A,B,C; Mat MUL(Mat x,Mat y,ll mod) { Mat tp; mem(tp.a,0); int n=x.n,m=y.m,l=x.m; tp.n=n,tp.m=m; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { tp.a[i][j]=0; for(int k=0; k<l; k++) { tp.a[i][j]=(tp.a[i][j]+x.a[i][k]*y.a[k][j]%mod)%mod; } } } return tp; } Mat POW(Mat tp,Mat x,ll n,ll mod) { while(n) { if(n&1) { tp=MUL(tp,x,mod); } n/=2; x=MUL(x,x,mod); } return tp; } void init() { A0.m=A0.n=5; mem(A0.a,0); A0.a[0][0]=a0*b0%Mod,A0.a[0][1]=a0%Mod,A0.a[0][2]=b0%Mod,A0.a[0][3]=1,A0.a[0][4]=0; A.m=A.n=5; mem(A.a,0); A.a[0][0]=ax*bx%Mod,A.a[1][0]=ax*by%Mod,A.a[2][0]=ay*bx%Mod,A.a[3][0]=ay*by%Mod; A.a[1][1]=ax%Mod,A.a[3][1]=ay%Mod,A.a[2][2]=bx%Mod,A.a[3][2]=by%Mod,A.a[3][3]=1; A.a[0][4]=1,A.a[4][4]=1; } void solve() { C=POW(A0,A,n,Mod);//A0*A^n ll ans=C.a[0][4]; printf("%I64d\n",ans); } int main() { while(scanf("%I64d",&n)!=EOF) { scanf("%I64d%I64d%I64d%I64d%I64d%I64d",&a0,&ax,&ay,&b0,&bx,&by); if(!n) { printf("0\n"); continue; } init(); solve(); } return 0; }
1005:将输入的两个字符对应一个16进制数,每个16进制数对应另一个16进制数,输入输出即可。