题解 LuoguP3306 [SDOI2013] 随机数生成器

题目链接:【LuoguP3306】

前置知识

OI-Wiki:快速幂扩展欧几里得算法(exgcd)Baby Step, Giant Step 算法

题意

很清楚,不说。

t=x

答案很明显为 1,即在第一天就可以读到。

tx

a=0

观察一下规律:

x1x1(modp)

x2b(modp)

规律十分显著:

xi{x1i=1bi>1(modp)

可以直接特判。

a=1

观察一下规律:

x1x1(modp)

x2x1+b(modp)

x3x1+2b(modp)

规律十分显著:

xix1+(i1)b(modp)

(i1)bxix1(modp)

然后就是用扩展欧几里得解同余方程了。

a>1

观察一下规律:

x1x1(modp)

x2ax1+b(modp)

x3a2x1+ab+b(modp)

规律十分显著:

xiai1x1+j=0i2ajb(modp)

很明显是一个等比数列。

等比数列如何求解?

首先设 S=j=0i2aj

aS=j=1i1aj

aSS=j=1i1ajj=0i2aj

(a1)S=ai11

S=ai11a1

j=0i1ajb=bj=0i1aj=bai11a1=b1ab1aai1

ai1xib1ax1b1a(modp)

ai1(a1)xi+b(a1)x1+b(modp)

然后求逆元之后利用 BSGS 算法求解同余高次方程。

最后可以发现其实推完公式之后就是 「SDOI2011」计算器

代码

//the code is from chenjh
#include<cstdio>
#include<cmath>
#include<unordered_map>
typedef long long LL;
LL qpow(LL a,int b,const int p){//快速幂。
	int ret=1;
	for(;b;b>>=1,a=a*a%p)if(b&1)ret=ret*a%p;
	return ret%p;
}
int exgcd(const int a,const int b,int&x,int&y){//扩展欧几里得。
	if(!b) return x=1,y=0,a;
	int d=exgcd(b,a%b,x,y);
	int z=x;x=y,y=z-y*(a/b);
	return d;
}
LL BSGS(int a,LL b,int p){//大步小步算法。
	std::unordered_map<LL,LL> h;h.clear();//std::unordered_map 基于哈希,理论上更快,实际上也比红黑树实现的 std::map 快。
	b%=p;
	int t=(LL)sqrt(p)+1;
	for(int j=0;j<t;j++) h[b*qpow(a,j,p)%p]=j;
	a=qpow(a,t,p);
	if(!a) return b?-1:1;
	for(int i=0;i<=t;i++){
		int v=qpow(a,i,p);
		LL j=h.find(v)==h.end()?-1:h[v];
		if(j>=0 && (LL)i*t-j>=0) return (LL)i*t-j;
	}
	return -1;
}
int main(){
	int T;scanf("%d",&T);
	for(int p,a,b,x,t;T--;){
		scanf("%d%d%d%d%d",&p,&a,&b,&x,&t);
		if(x==t) puts("1");
		else if(!a) puts(t==b?"2":"-1");
		else if(a==1){
			int X,Y;
			int g=exgcd(b,p,X,Y);
			int B=((LL)t-x+p)%p;
			printf("%d\n",B%g?-1:int(((LL)B/g*X%(p/g)+p/g)%(p/g)+1));//求解线性同余方程。
		}
		else{
			LL B=((LL)(a-1)*t+b)%p*qpow(((LL)(a-1)*x+b)%p,p-2,p)%p;
			int ans=BSGS(a,B,p);
			printf("%d\n",ans<0?-1:ans+1);
		}
	}
	return 0;
}
posted @   Chen_Jinhui  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App

一言

倘若只是为了驱赶心中的寂寞,找谁都可以的。
——秒速5厘米
点击右上角即可分享
微信分享提示