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 }

 


posted @ 2017-04-02 19:38  嘘丶  阅读(282)  评论(0编辑  收藏  举报