【CODEVS1281】Xn数列

Description

给你6个数,m, a, c, x0, n, g

Xn+1 = ( aXn + c ) mod m,求Xn

m, a, c, x0, n, g<=10^18

Input

一行六个数 m, a, c, x0, n, g

Output

输出一个数 Xn mod g

Sample Input

11 8 7 1 5 3

Sample Output

2

HINT

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

题解

对于取模运算进行一个修改,将乘法修改为倍增乘法(类似于快速幂):

long long Multiply (long long x, long long y)
{
    long long ans = 0;
    while(y)
    {
        if(y & 1) ans = (ans + x) % m;
        x = (x << 1) % m;
        y >>= 1;
    }
    return ans;
}
代码粘黄学长的

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long m,a,c,x0,n,g;
long long Multiply (long long x,long long y)
{
    long long ans=0;
    while (y)
    {
        if (y&1) ans=(ans+x)%m;
        x=(x<<1)%m;
        y>>=1;
    }
    return ans;
}
void mul(long long a[2][2],long long b[2][2])
{
    long long c[2][2]={{0,0},{0,0}};
    for (int i=0;i<2;i++)
        for (int j=0;j<2;j++)
            for (int k=0;k<2;k++)
                c[i][j] = (c[i][j]+Multiply(a[i][k],b[k][j]))%m;//就是这里 
    memcpy(a,c,sizeof(c));
}
int main()
{
    cin>>m>>a>>c>>x0>>n>>g;
    long long f[2][2] = {{x0,1},{0,0}};
    long long b[2][2] = {{a,0},{c,1}};
    while(n)
    {
        if (n&1) mul(f,b);
        mul(b,b);
        n >>= 1;
    }
    cout<<f[0][0]%g;
}

 

你可能感兴趣的:(【CODEVS1281】Xn数列)