首页 > 其他分享 >题解 LuoguP3306 [SDOI2013] 随机数生成器

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

时间:2023-08-11 10:12:46浏览次数:53  
标签:LuoguP3306 limits int 题解 LL 生成器 pmod sum equiv

题目链接:【LuoguP3306】

前置知识

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

题意

很清楚,不说。

分析

当 \(t=x\) 时

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

当 \(t\neq x\) 时

当 \(a=0\) 时

观察一下规律:

\[x_1\equiv x_1\pmod{p} \]

\[x_2\equiv b\pmod{p} \]

规律十分显著:

\[x_i\equiv\begin{cases}x_1&i=1\\b&i>1\end{cases}\pmod{p} \]

可以直接特判。

当 \(a=1\) 时

观察一下规律:

\[x_1\equiv x_1\pmod{p} \]

\[x_2\equiv x_1+b\pmod{p} \]

\[x_3\equiv x_1+2b\pmod{p} \]

规律十分显著:

\[x_i\equiv x_1+(i-1)b\pmod{p} \]

\[(i-1)b\equiv x_i-x_1\pmod{p} \]

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

当 \(a>1\) 时

观察一下规律:

\[x_1\equiv x_1\pmod{p} \]

\[x_2\equiv ax_1+b\pmod{p} \]

\[x_3\equiv a^2x_1+ab+b\pmod{p} \]

规律十分显著:

\[x_i\equiv a^{i-1}x_1+\sum\limits_{j=0}^{i-2}a^jb\pmod{p} \]

很明显是一个等比数列。

等比数列如何求解?

首先设 \(S=\sum\limits_{j=0}^{i-2}a^j\)。

\[aS=\sum\limits_{j=1}^{i-1}a^j \]

\[aS-S=\sum\limits_{j=1}^{i-1}a^j-\sum\limits_{j=0}^{i-2}a^j \]

\[(a-1)S=a^{i-1}-1 \]

\[S=\dfrac{a^{i-1}-1}{a-1} \]

\[\sum\limits_{j=0}^{i-1}a^jb = b\sum\limits_{j=0}^{i-1}a^j= b\dfrac{a^{i-1}-1}{a-1}=\dfrac{b}{1-a}-\dfrac{b}{1-a}a^{i-1} \]

\[a^{i-1}\equiv\dfrac{x_i-\frac{b}{1-a}}{x_1-\frac{b}{1-a}}\pmod{p} \]

\[a^{i-1}\equiv\dfrac{(a-1)x_i+b}{(a-1)x_1+b}\pmod{p} \]

然后求逆元之后利用 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;
}

标签:LuoguP3306,limits,int,题解,LL,生成器,pmod,sum,equiv
From: https://www.cnblogs.com/Chen-Jinhui/p/solution-p3306.html

相关文章

  • HDU 多校 Round #6 题解
    HDU多校Round#6题解\(\text{ByDaiRuiChen007}\)A.CountProblemLink题目大意求有多少个长度为\(n\),字符集大小为\(m\)的字符串有长度为\(n-k\)的周期。数据范围:\(n,m,k\le10^{18}\)。思路分析\(k=n\)时答案为\(m^n\),否则转为有长度为\(k\)的Border,答案......
  • Royal Questions题解
    题目链接RoyalQuestions-洛谷|计算机科学教育新生态(luogu.com.cn)分析每个公主会选择两个王子,考虑将每个公主所选择的两个王子连边,边权为该公主的嫁妆选择该边即为选择该公主那么结果图是什么呢?由于每个王子最多只能选择一个公主即每个点最多有1个出边(也可能没有出边......
  • 【题解】Educational Codeforces Round 148(CF1832)
    A.NewPalindrome题目描述:给你一个由小写字母组成的回文字符串,问你是否能在重排其之后构造出另一个与原串不同的回文字符串。多测,\(t\le1000,2\le|s|\le50\)题目分析:考虑其实就是前\(\lfloor\frac{n}{2}\rfloor\)个位置存在两种或以上的不同字符,因为这样直接交换对......
  • P2203 Blink 题解
    好像并没有矩阵快速幂的题解,那我来写一篇题目分析对于每两盏灯,只考虑右灯变化,分为四种情况:左灯为\(1\),右灯为\(1\),右灯变为\(0\);左灯为\(0\),右灯为\(0\),右灯不变,为\(0\);左灯为\(1\),右灯为\(0\),右灯变为\(1\);左灯为\(0\),右灯为\(1\),右灯不变,为\(1\);设第\(i\)......
  • P9342 Bitaro's Travel 题解
    模拟赛做到的题,赛后看了Y2hlbnlpa2Fp的题解,感觉没讲清楚,这里做下补充,提供自己的理解。基本思路:对每个\(A_i\)的答案进行预处理,对于每个询问,只需要找到第一个到达的景点即可。那么如何预处理每个点的答案呢?有一条很重要的性质:最多转向\(\log{X}\)次。要证明这个结论,先放......
  • P6879 スタンプラリー 3 题解
    思路前几篇题解都介绍了,这里着重介绍一个状态设计的小技巧。在设计状态时,我们可能会碰到状态数值过大,而dp数组内存的值较小的情况。例如在该题用\(dp_{l,r,t,0/1}\)表示逆时针经过\(l\)个,顺时针经过\(r\)个,已经花费\(t\)秒,所拿到的雕像个数,\(0\)表示当前在左端点,\(1\)......
  • AT_apc001_g Colorful Doors 题解
    模拟赛做到的题,场上写贪心爆栈了qwq首先在首尾加上两个\(1\)表示进出,将两段路中间的间隔作为传送门,恰好有\(2\timesN\)个传送门,根据两段路的经过情况给传送门分类别:00:用\(N\)表示,称为无用点,不到达该点。10:用\(S\)表示,称为起点,需要通过向右走走到一次。01:用\(T\)......
  • 什么是迭代器,生成器,装饰器;django的信号用过吗?如何用,干过什么;什么是深拷贝,什么是浅拷贝
    什么是迭代器,生成器,装饰器;django的信号用过吗?如何用,干过什么;什么是深拷贝,什么是浅拷贝,如何使用什么是迭代器,生成器,装饰器#迭代器-迭代:一种不依赖于索引取值的方式,我们不需要关注它的位置,只要能够一个个取值,它就称之为迭代,python中就是for循环,内部调用对象.__next__()-可迭......
  • 关于Promise的超难面试题解读
    让我来看一下题目,如下所示Promise.resolve().then(()=>{ console.log(0); returnPromise.resolve(4); }).then((res)=>{ console.log(res); }); Promise.resolve().then(()=>{ console.log(1); }).then(()=>{ console.log(2); }).t......
  • 题解 [SDOI2009] Elaxia的路线
    题目链接题意简述:求两条给定起点终点最短路的最长公共路径。首先最长公共路径一定是两条最短路的公共最长链的部分。至少一定在两条最短路上。考虑如何求出一条路径是否包含于一条最短路,只要路径\(x\rightarrowy\)满足:\[dis_{st\rightarrowx}+w_{x\rightarrowy}+dis_{y\r......