Xn数列
1281 Xn数列
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 大师 Master
题目描述 Description
给你6个数,m, a, c, x0, n, g
Xn+1 = ( aXn + c ) mod m,求Xn
m, a, c, x0, n, g<=10^18
输入描述 Input Description
一行六个数 m, a, c, x0, n, g
输出描述 Output Description
输出一个数 Xn mod g
样例输入 Sample Input
11 8 7 1 5 3
样例输出 Sample Output
2
矩阵快速幂优化递推,
初始矩阵:
x0 |
c |
0 |
0 |
递推矩阵:
a |
0 |
1 |
1 |
然后要搞个龟速乘,防止乘法溢出。
1 #include<set> 2 #include<map> 3 #include<queue> 4 #include<stack> 5 #include<ctime> 6 #include<cmath> 7 #include<string> 8 #include<vector> 9 #include<cstdio> 10 #include<cstdlib> 11 #include<cstring> 12 #include<iostream> 13 #include<algorithm> 14 #define LL long long 15 using namespace std; 16 LL b[2][2][2],s[2][2]; 17 LL qmul(LL a1,LL b1,LL mod){ 18 LL ans=0; 19 while(b1){ 20 if(b1&1) ans+=a1,ans%=mod; 21 b1>>=1; 22 a1*=2,a1%=mod; 23 } 24 return ans; 25 } 26 void Count(int a1,int b1,LL mod){ 27 for(int i=0;i<2;i++) 28 for(int j=0;j<2;j++) 29 for(int k=0;k<2;k++) 30 s[i][j]=(s[i][j]+qmul(b[a1][i][k],b[b1][k][j],mod)%mod)%mod; 31 for(int i=0;i<2;i++) 32 for(int j=0;j<2;j++) 33 b[a1][i][j]=s[i][j],s[i][j]=0; 34 } 35 void qpow(LL n,LL m){ 36 while(n){ 37 if(n&1) Count(0,1,m); 38 n>>=1; 39 Count(1,1,m); 40 } 41 } 42 int main() 43 { 44 freopen("!.in","r",stdin); 45 freopen("!.out","w",stdout); 46 LL m,a,c,x0,n,g; 47 scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x0,&n,&g); 48 b[0][0][0]=x0,b[0][0][1]=c; 49 b[1][0][0]=a,b[1][1][0]=1,b[1][1][1]=1; 50 qpow(n,m); 51 printf("%lld",b[0][0][0]%g); 52 return 0; 53 }