您的位置:首页 > 其它

【矩阵乘法+快速乘】BZOJ2875-[NOI2012]随机数生成器

2016-07-10 11:27 302 查看
【题目大意】

已知Xn+1=(aXn+c) mod m,求Xn mod g。

【思路】

get到了longlong乘法的正确方法,快速乘。什么是快速乘呢?


简单来讲,快速幂就是模拟了二进制的竖式乘法。如:

10101 × 1011 = 10101*1+10101*2^1*1+10101*2^2*0+10101*2^3*1

代码如下:

long long multi(long long a,long long b,long long m) {
long long ans=0;

while(b) {
if(b&1) (ans+=a) %= m;
(a=a*2) %= m;
b/=2;
}

return ans;
}



接下来本题的方法就是据矩阵乘法的快速幂

(a 0

c 1)自乘n次即可

注意函数里也不要忘记了开longlong..一开始我函数里面的n写成了int,WA了一发。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
ll matrix[2][2],ans_matrix[2][2];
ll m,n,a,c,g,x0;

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

void ksm(ll n)
{
ans_matrix[0][0]=ans_matrix[1][1]=1;
ans_matrix[0][1]=ans_matrix[1][0]=0;
while (n)
{
if (n&1)
{
ans_matrix[0][0]=ksc(ans_matrix[0][0],matrix[0][0]);
ans_matrix[1][0]=(ksc(ans_matrix[1][0],matrix[0][0])+matrix[1][0])%m;
}
n>>=1;
ll tmp1=ksc(matrix[0][0],matrix[0][0]);
ll tmp2=(ksc(matrix[1][0],matrix[0][0])+matrix[1][0])%m;
matrix[0][0]=tmp1,matrix[1][0]=tmp2;
}
}

void init()
{
scanf("%lld%lld%lld%lld%lld%lld",&m,&a,&c,&x0,&n,&g);
matrix[0][0]=a%m,matrix[0][1]=0,matrix[1][0]=c%m,matrix[1][1]=1;
}

void get_ans()
{
ll ans=(ksc(ans_matrix[0][0],x0)+ans_matrix[1][0])%m;
ans%=g;
printf("%lld",ans);
}

int main()
{
//freopen("randoma.in","r",stdin);
//freopen("randoma.out","w",stdout);
init();
ksm(n);
get_ans();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: