「Luogu3306」[SDOI2013]随机数生成器


「Luogu3306」[SDOI2013]随机数生成器

problem

Solution

我们来回忆一下数列递推公式求通项的方法

\(Y_i=X_i+\frac{b}{a-1}\),则有

\[Y_i=aY_{i-1}\Rightarrow Y_i=a^{i-1}Y_1 \]

于是题目转化为求解方程

\[t+\frac b{a-1}\equiv a^{x-1}(X_1+\frac b{a-1})\pmod p \]

\[\Rightarrow a^{x-1}\equiv\frac{t+\frac b{a-1}}{X_1+\frac b{a-1}}\pmod p \]

好的,这个东西我们只要用BSGS就可以了

End?


几个细节:

\(X_1=t\)时,直接输出\(1\)

\(a=0\)时,输出若\(b=t\)则输出\(2\),否则无解,\(X_1=t\)的情况已经特判

\(a=1\)时,方程实际上为

\[(x-1)b\equiv t-X_1\pmod p \]

根据裴蜀定理判掉无解,然后直接算\(x-1\)即可

需要注意的是如果\(\frac{t-X_1} b=p\),则不需要取模直接输出

True End

Code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define mp(x,y) (make_pair((x),(y)))
#define inv(x) (fastpow((x),p-2))
using namespace std;
typedef long long ll;

template void read(T &t)
{
	t=0;int f=0;char c=getchar();
	while(!isdigit(c)){f|=c=='-';c=getchar();}
	while(isdigit(c)){t=t*10+c-'0';c=getchar();}
	if(f)t=-t;
}

int T;

ll p,a,b,X1,t;
ll m;

ll fastpow(ll a,ll b)
{
	ll re=1,base=a;
	while(b)
	{
		if(b&1)
			re=re*base%p;
		base=base*base%p;
		b>>=1;
	}
	return re;
}

map rec;
void Pre()
{
	rec.clear();
	ll tmp=1;
	for(register int i=0;i