您的位置:首页 > 编程语言 > C语言/C++

C++之路进阶——矩阵乘法(Xn数列)

2016-02-15 21:17 561 查看

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

数据范围及提示 Data Size & Hint

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

题解:

1.俄罗斯农夫算法。

2.矩阵 {(a,0)(1,1)},{Xn,c}

3.要用快速幂。

代码:

#include<cstdio>
#include<iostream>
#define ll long long

using namespace std;

long long m,a,c,x0,n,g;
long long x[2][2],b[2][2],f[1][2];

long long mull(long long a,long long b,long long m)
{
long long ans=0;
while (b)
{
if (b&1) ans=(a+ans)%m;
b>>=1;
a=(a<<1)%m;
}
return ans;
}

int mull1 (long long a[2][2],long long b[2][2],long long ans[2][2])
{
long long c[2][2];
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
{
c[i][j]=0;
for (int k=0;k<2;k++)
c[i][j]=(c[i][j]+mull(a[i][k],b[k][j],m))%m;
}
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
ans[i][j]=c[i][j];
}

int mull2 (long long a[1][2],long long b[2][2],long long ans[1][2])
{
long long c[1][2];
for (int i=0;i<1;i++)
for (int j=0;j<2;j++)
{
c[i][j]=0;
for (int k=0;k<2;k++)
c[i][j]=(c[i][j]+mull(a[i][k],b[k][j],m))%m;
}
for (int i=0;i<2;i++)
ans[0][i]=c[0][i];
}

int main()
{
scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x0,&n,&g);
x[0][0]=a;
x[1][0]=x[1][1]=1;
b[0][0]=b[1][1]=1;
f[0][0]=x0;f[0][1]=c;
while (n)
{
if (n&1) mull1(x,b,b);
mull1(x,x,x);
n>>=1;
}
mull2(f,b,f);
printf("%lld\n",f[0][0]%g);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: