【bzoj2875】随机数生成器(矩乘快速幂+快速乘)

本文介绍了一种使用矩阵快速幂解决特定类型问题的方法。通过初始化特定矩阵,并采用高效的乘法策略来避免溢出问题,确保计算精度。文章提供了一个实际的C++代码示例,演示了如何实现矩阵快速幂算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:我是超链接

题解:

矩阵快速幂裸题?

初始化的矩阵|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);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值