Codevs No.1281 Xn数列

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 }

 

转载于:https://www.cnblogs.com/Neptune-/p/5550105.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值