【bzoj2875】随机数生成器(矩乘快速幂+快速乘)
2017-09-05 14:41
267 查看
题目:我是超链接
题解:
矩阵快速幂裸题?
初始化的矩阵|x0 c|
准备乘的矩阵|a 0|
|1 1|
这样就会发现是正确的,最后两个点是爆longlong的,乘的时候需要用快速乘(与快速幂不同的地方就是把*变成+)
还有一件事,你只需要把矩阵求出来最后的最后%g,中间一直要%m(kp)
一个自认为很优美的代码:
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
LL m,aa,c,n,g,x;
struct hh{LL sq[5][5];void cl(){memset(sq,0,sizeof(sq));}}ans,mult,a;
LL mul(LL a,LL b){
LL res=0;
for(;b;b>>=1,a=(a+a)%m) if(b&1) res=(res+a)%m;
return res;
}
hh work(hh a,hh b)
{
int i,j,k;
hh c;c.cl();
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++)
c.sq[i][j]=(c.sq[i][j]+mul(a.sq[i][k],b.sq[k][j])%m)%m;
return c;
}
hh ksm(LL k)
{
hh a;a=mult;
for (;k;k>>=1,a=work(a,a))
if (k&1) mult=work(mult,a);
return mult;
}
int main()
{
int i,j,k;
scanf("%lld%lld%lld%lld%lld%lld",&m,&aa,&c,&x,&n,&g);
a.sq[1][1]=x; a.sq[1][2]=c;
mult.sq[1][1]=aa; mult.sq[1][2]=0; mult.sq[2][1]=1; mult.sq[2][2]=1;
if (n>1) mult=ksm(n-1);
for (i=1;i<=1;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++)
ans.sq[i][j]=(ans.sq[i][j]+mul(a.sq[i][k],mult.sq[k][j])%m)%m;
printf("%lld",ans.sq[1][1]%g);
}
题解:
矩阵快速幂裸题?
初始化的矩阵|x0 c|
准备乘的矩阵|a 0|
|1 1|
这样就会发现是正确的,最后两个点是爆longlong的,乘的时候需要用快速乘(与快速幂不同的地方就是把*变成+)
还有一件事,你只需要把矩阵求出来最后的最后%g,中间一直要%m(kp)
一个自认为很优美的代码:
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
LL m,aa,c,n,g,x;
struct hh{LL sq[5][5];void cl(){memset(sq,0,sizeof(sq));}}ans,mult,a;
LL mul(LL a,LL b){
LL res=0;
for(;b;b>>=1,a=(a+a)%m) if(b&1) res=(res+a)%m;
return res;
}
hh work(hh a,hh b)
{
int i,j,k;
hh c;c.cl();
for (i=1;i<=2;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++)
c.sq[i][j]=(c.sq[i][j]+mul(a.sq[i][k],b.sq[k][j])%m)%m;
return c;
}
hh ksm(LL k)
{
hh a;a=mult;
for (;k;k>>=1,a=work(a,a))
if (k&1) mult=work(mult,a);
return mult;
}
int main()
{
int i,j,k;
scanf("%lld%lld%lld%lld%lld%lld",&m,&aa,&c,&x,&n,&g);
a.sq[1][1]=x; a.sq[1][2]=c;
mult.sq[1][1]=aa; mult.sq[1][2]=0; mult.sq[2][1]=1; mult.sq[2][2]=1;
if (n>1) mult=ksm(n-1);
for (i=1;i<=1;i++)
for (j=1;j<=2;j++)
for (k=1;k<=2;k++)
ans.sq[i][j]=(ans.sq[i][j]+mul(a.sq[i][k],mult.sq[k][j])%m)%m;
printf("%lld",ans.sq[1][1]%g);
}
相关文章推荐
- BZOJ2875: [Noi2012]随机数生成器 矩阵乘法+快速乘
- [BZOJ2875][Noi2012]随机数生成器 && 矩阵+快速乘
- 【BZOJ】2875: [Noi2012]随机数生成器(矩阵乘法+快速乘)
- BZOJ-2875 随机数生成器 矩阵乘法快速幂+快速乘
- BZOJ2875 [Noi2012]随机数生成器 【矩阵乘法 + 快速乘】
- BZOJ-2875 随机数生成器 矩阵乘法快速幂+快速乘
- BZOJ2875: [Noi2012]随机数生成器 矩阵乘法+快速乘
- 【BZOJ2875】[Noi2012]随机数生成器【矩阵快速幂】
- BZOJ 2875[Noi2012]随机数生成器(矩阵快速幂+小技巧)
- [BZOJ2875] [NOI2012] 随机数生成器 - 矩阵快速幂
- [BZOJ 2875 & Vijos 1725] NOI 2012 随机数生成器 · 矩阵乘法+快速乘法
- 【矩阵乘法+快速乘】BZOJ2875-[NOI2012]随机数生成器
- 【BZOJ2875】随机数生成器(矩阵快速幂)
- [BZOJ 2875][NOI 2012]随机数生成器(矩阵快速幂)
- BZOJ 2875: [Noi2012]随机数生成器( 矩阵快速幂 )
- 【NOI2012】【BZOJ2875】随机数生成器
- BZOJ 2875: [Noi2012]随机数生成器【矩阵乘法优化递推
- [BZOJ2875][NOI2012]随机数生成器(矩阵乘法)
- BZOJ 2875 [Noi2012] 随机数生成器 题解与分析
- 【bzoj2875】 Noi2012—随机数生成器