2875: [Noi2012]随机数生成器
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 515 Solved: 281
[ Submit ][ Status ]
Description
栋栋最近迷上了随机算法,而随机数生成是随机算法的基础。栋栋准备使用线性同余法(Linear
Xn+1=
其中
Input
包含6个用空格分割的m,a,c,X0,n和g,其中a,c,X0是非负整数,m,n,g是正整数。
Output
输出一个数,即Xn mod g
Sample Input
11 8 7 1 5 3
Sample Output
HINT
样例说明:
因此答案为
Source
【分析】:
用矩阵乘法做:
最后两个点答案会超long long,将乘法改为倍增加法,边加边取模
【代码】:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define MAX 3
struct mat{long long c[MAX][MAX];};
long long M,A,C,X0,N,G;
long long mult1(long long A,long long B)
{
long long tmp=0;
while(B!=0)
{
if(B&1) tmp=(tmp+A)%M;
B>>=1;
A=(A<<1)%M;
}
return tmp%M;
}
mat mult(mat A,mat B)
{
mat now;
for(int i=1;i<=2;i++)
for(int j=1;j<=2;j++)
{
now.c[i][j]=0;
for(int k=1;k<=2;k++)
now.c[i][j]=(now.c[i][j]+mult1(A.c[i][k],B.c[k][j]))%M;
}
return now;
}
mat power(mat now,long long n)
{
if(n==1) return now;
else if(n&1)
return mult(power(now,n-1),now);
else
{
mat use;
use=power(now,n/2);
return mult(use,use);
}
}
mat a,ans;
void work()
{
mat now;
a.c[1][1]=A;a.c[1][2]=0;
a.c[2][1]=C;a.c[2][2]=1;
now=power(a,N);
ans.c[1][1]=X0;ans.c[1][2]=1;
ans.c[2][1]=0;ans.c[2][2]=0;
ans=mult(ans,now);
}
int main()
{
//freopen("random.in","r",stdin);
//freopen("random.out","w",stdout);
scanf("%lld%lld%lld%lld%lld%lld",&M,&A,&C,&X0,&N,&G);
work();
printf("%lld\n",ans.c[1][1]%G);
//system("pause");
return 0;
}