2016-06-01 16:28:25
题目链接: Xn数列 (Codevs No.1281)
题目大意:
给定一种递推式为 Xn=(A*Xn-1+C)%M 的数列,求特定的某一项%G
解法:
矩阵乘法
不会的去看看高中矩阵的那本选修,起码知道都是啥意思,好理解得多
矩阵构造: 向量构造:
A C X0
0 1 1
需要注意的地方:
1.超大整数乘法,写个快速乘,防止爆longlong
2.函数的代值类型千万别错了啊,一个longlong打成int爆了一个多小时
1 //Xn数列 (Codevs No.1281) 2 //矩阵乘法 3 #include<stdio.h> 4 #include<algorithm> 5 using namespace std; 6 long long a[3][3]; 7 long long b[3][3]; 8 long long c[3][3]; 9 long long M,A,C,X,N,G; 10 long long ans; 11 long long mX(long long x, long long y) 12 { 13 long long s=0,k=0; 14 while(y>0) 15 { 16 if(y&1)s=(s+x)%M; 17 x=(x<<1)%M; 18 y=y>>1; 19 } 20 return s; 21 } 22 void Multi1() 23 { 24 for(int i=1;i<=2;i++) 25 { 26 for(int j=1;j<=2;j++) 27 { 28 c[i][j]=0; 29 for(int k=1;k<=2;k++) 30 { 31 c[i][j]=(c[i][j]%M+mX(a[i][k],b[k][j])%M)%M; 32 } 33 } 34 } 35 for(int i=1;i<=2;i++) 36 { 37 for(int j=1;j<=2;j++) 38 { 39 a[i][j]=c[i][j]; 40 } 41 } 42 return ; 43 } 44 void Multi2() 45 { 46 for(int i=1;i<=2;i++) 47 { 48 for(int j=1;j<=2;j++) 49 { 50 c[i][j]=0; 51 for(int k=1;k<=2;k++) 52 { 53 c[i][j]=(c[i][j]%M+mX(b[i][k],b[k][j])%M)%M; 54 } 55 } 56 } 57 for(int i=1;i<=2;i++) 58 { 59 for(int j=1;j<=2;j++) 60 { 61 b[i][j]=c[i][j]; 62 } 63 } 64 return ; 65 } 66 void Bpow(long long x) 67 { 68 while(x) 69 { 70 if(x&1)Multi1(); 71 Multi2(); 72 x>>=1; 73 } 74 return ; 75 } 76 int main() 77 { 78 scanf("%lld %lld %lld %lld %lld %lld",&M,&A,&C,&X,&N,&G); 79 a[2][2]=b[2][2]=1; 80 a[1][1]=b[1][1]=A%M; 81 a[1][2]=b[1][2]=C%M; 82 Bpow(N-1); 83 ans=(mX(a[1][1],X)+a[1][2])%M; 84 printf("%lld",ans%G); 85 }