【bzoj2875随机数生成器】【codevs3332】
2015-03-18 17:04
337 查看
2875: [Noi2012]随机数生成器
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1007 Solved: 577
[Submit][Status][Discuss]
Description
Input
包含6个用空格分割的m,a,c,X0,n和g,其中a,c,X0是非负整数,m,n,g是正整数。Output
输出一个数,即Xn mod gSample Input
11 8 7 1 5 3Sample Output
2一道比较水的矩阵乘法的题。很容易可以看出我们的答案是这样得出的
然后我们在用快速幂求出前面的n次方再乘上
就行了。
需要注意的是,由于可能会在乘的时候炸掉,所以我们可以写一个快速乘,这样就不用写高精度了。
#include<iostream> #include<cstdio> #include<cstring> #define F(i,x,y) for(i=x;i<=y;++i) #include<algorithm> using namespace std; long long M,A,C,X0,N,G,a[2][2]={0},ans[2][2],c[2][2]; bool f=true; long long quickcheng(long long x,long long y) { long long out=0; x=x%M;y=y%M; if(x>y) swap(x,y); while(y) { if(y&1) out=(out+x)%M; y>>=1; x=(x+x)%M; } return out; } int main() { long long i,j,k,y,out; cin>>M>>A>>C>>X0>>N>>G; a[0][0]=A;a[0][1]=C;a[1][0]=0;a[1][1]=1; y=N; while(y){ if(y&1){ if(f){ F(i,0,1) F(j,0,1) ans[i][j]=a[i][j]; f=false; } else{ F(i,0,1) F(j,0,1) { c[i][j]=0; F(k,0,1) c[i][j]=(c[i][j]+quickcheng(a[i][k],ans[k][j]))%M; } F(i,0,1) F(j,0,1) ans[i][j]=c[i][j]; } } y>>=1; F(i,0,1) F(j,0,1) { c[i][j]=0; F(k,0,1) c[i][j]=(c[i][j]+quickcheng(a[i][k],a[k][j]))%M; } F(i,0,1) F(j,0,1) a[i][j]=c[i][j]; } out=(quickcheng(ans[0][0],X0)+ans[0][1])%M; out=out%G; cout<<out<<endl; }
3332 数列
题目描述 Description
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
输入描述 Input Description
第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。
输出描述 Output Description
每行输出一个非负整数表示答案
样例输入 Sample Input
3
6
8
10
样例输出 Sample Output
4
9
19
数据范围及提示 Data Size & Hint
对于30%的数据 n<=100;
对于60%的数据 n<=2*10^7;
对于100%的数据 T<=100,n<=2*10^9;
这个题和上面那个题的思路差不多。我们需要这样一个式子
然后就可以了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define F(i,x,y) for(i=x;i<=y;++i) #define m 1000000007 using namespace std; int t,n; long long a[3][3]={0},ans[3][3],c[3][3]; bool f=true; int main() { scanf("%d",&t); while(t--){ int i,j,y,out,k; scanf("%d",&n); memset(a,0,sizeof(a)); a[0][0]=a[0][2]=a[1][0]=a[2][1]=1; f=true;y=n-3; if(n<=3) printf("1\n"); else{ while(y){ if(y&1){ if(f){ F(i,0,2) F(j,0,2) ans[i][j]=a[i][j]; f=false; } else{ F(i,0,2) F(j,0,2) { c[i][j]=0; F(k,0,2) c[i][j]=(c[i][j]+(a[i][k]*ans[k][j])%m)%m; } F(i,0,2) F(j,0,2) ans[i][j]=c[i][j]; } } y>>=1; F(i,0,2) F(j,0,2) { c[i][j]=0; F(k,0,2) c[i][j]=(c[i][j]+(a[i][k]*a[k][j])%m)%m; } F(i,0,2) F(j,0,2) a[i][j]=c[i][j]; } out=(ans[0][0]+ans[0][1]+ans[0][2])%m; printf("%d\n",out); } } }
相关文章推荐
- BZOJ_P2875&Codevs_P1281 [NOI2012]随机数生成器(数论+矩阵乘法)
- bzoj2875 [Noi2012]随机数生成器 [矩阵+快乘]
- [BZOJ2875][Noi2012]随机数生成器 && 矩阵+快速乘
- [BZOJ 2875 & Vijos 1725] NOI 2012 随机数生成器 · 矩阵乘法+快速乘法
- BZOJ2875: [Noi2012]随机数生成器 矩阵乘法+快速乘
- BZOJ 2875 2875: [NOI2012]随机数生成器
- [NOI2012] 随机数生成器 [CodeVS1281] Xn数列
- bzoj2875 [noi2012]随机数生成器(矩阵倍增)
- 【bzoj2875】 Noi2012—随机数生成器
- bzoj2875 [Noi2012]随机数生成器
- BZOJ 2875[Noi2012]随机数生成器(矩阵快速幂+小技巧)
- BZOJ2875 [Noi2012]随机数生成器
- [BZOJ2875][NOI2012]随机数生成器(矩阵乘法)
- bzoj 2875: [Noi2012]随机数生成器
- 2875: [Noi2012]随机数生成器 - BZOJ
- [bzoj2875][Noi2012]随机数生成器
- BZOJ 2875 随机数生成器
- 【Bzoj2875】随机数生成器
- 【bzoj2875】随机数生成器(矩乘快速幂+快速乘)
- BZOJ 2875: [Noi2012]随机数生成器【矩阵乘法优化递推