您的位置:首页 > 其它

【codevs1281】Xn数列,矩阵乘法练习

2016-02-15 19:03 375 查看
时间限制: 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

数据范围及提示 Data Size & Hint

int64按位相乘可以不要用高精度。

写在前面:数论!数论!

思路:

转移矩阵:

{a,1}

{0,1}

初始矩阵:

{Xn}

{ c }

要加一个无聊的乘法优化,要不会炸longlong

#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL m,a,c,x0,n,g;
struct matrix
{
LL map[3][3];
void clear(){memset(map,0,sizeof(map));}
};
LL cheng(LL x,LL y)//乘法优化,参照快速幂
{
LL ans=0;
while (y)
{
if (y&1) ans=(ans+x)%m;
x=(x+x)%m;
y>>=1;
}
return ans;
}
matrix mul(matrix x,matrix y)//矩阵乘法
{
matrix z;
z.clear();
for (int i=1;i<=2;i++)
for (int j=1;j<=2;j++)
for (int k=1;k<=2;k++)
z.map[i][j]=(z.map[i][j]+cheng(x.map[i][k],y.map[k][j])%m)%m;
return z;
}
main()
{
scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x0,&n,&g);
matrix x,ans;//ans为初始,x为转移
x.clear();
ans.clear();
ans.map[1][1]=x0;
ans.map[2][1]=c;
x.map[1][1]=a;
x.map[1][2]=1;
x.map[2][1]=0;
x.map[2][2]=1;
while (n)
{
if (n&1) ans=mul(x,ans);
x=mul(x,x);
n>>=1;
}
printf("%lld",ans.map[1][1]%g);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: