[SDOI2013]随机数生成器

Description

Input
输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数。
接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据。保证X1和t都是合法的页码。
注意:P一定为质数

Output
共T行,每行一个整数表示他最早读到第t页是哪一天。如果他永远不会读到第t页,输出-1。

Sample Input
3
7 1 1 3 3
7 2 2 2 0
7 2 2 2 1

Sample Output
1
3
-1

HINT
\(0\leqslant a\leqslant P-1,0\leqslant b\leqslant P-1,2\leqslant P\leqslant10^9\)


我们推推式子可以发现

\[X_n=a^{n-1}X_1+\sum\limits_{i=0}^{n-2}a^ib \]

然后后面那玩意显然是等比数列,然后我们就可以得到

\[\begin{align}X_n&=a^{n-1}X_1+\dfrac{b(1-a^{n-1})}{1-a}\nonumber\\&=a^{n-1}X_1+\dfrac{b}{1-a}-\dfrac{ba^{n-1}}{1-a}\nonumber\\&=a^{n-1}(X_1-\dfrac{b}{1-a})+\dfrac{b}{1-a}\nonumber\\\Longrightarrow\dfrac{X_nb}{1-a}&=a^{n-1}(X_1-\dfrac{b}{1-a})\nonumber\end{align} \]

然后直接用扩展BSGS就好了

/*program from Wolfycz*/
#include<map>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
#define Fi first
#define Se second
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
	static char buf[1000000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>inline T frd(T x){
	int f=1; char ch=gc();
	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
template<typename T>inline T read(T x){
	int f=1;char ch=getchar();
	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
	return x*f;
}
inline void print(int x){
	if (x<0)    putchar('-'),x=-x;
	if (x>9)	print(x/10);
	putchar(x%10+'0');
}
map<int,int>Mp;
int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int mlt(int a,int b,int p){
	int res=1;
	for (;b;b>>=1,a=1ll*a*a%p)	if (b&1)	res=1ll*res*a%p;
	return res;
}
int BSGS(int a,ll c,int p){
	Mp.clear();
	if (a==c)	return 1;
	int lmt=(int)sqrt(p);
	for (int i=0;i<lmt;i++){
		int res=1ll*c*mlt(a,i,p)%p;
		map<int,int>::iterator it=Mp.find(res);
		if (it==Mp.end())	it=Mp.insert(map<int,int>::value_type(res,i)).Fi;
		it->Se=i;
	}
	for (int i=1;i*lmt<p;i++){
		int res=mlt(a,i*lmt,p);
		map<int,int>::iterator it=Mp.find(res);
		if (it!=Mp.end())	return i*lmt-it->Se;
	}
	return -1;
}
int main(){
	for (int Data=read(0);Data;Data--){
		int p=read(0),a=read(0),b=read(0),k=read(0),t=read(0);
		if (k==t){
			printf("1\n");
			continue;
		}
		if (!a){
			printf(b==t?"2\n":"-1\n");
			continue;
		}
		if (a==1){
			int Ans=1ll*(t-k)*mlt(b,p-2,p)%p;
			printf(!b?"-1\n":"%d\n",(Ans+p)%p+1);
			continue;
		}
		ll x=t-1ll*a*t-b,y=k-1ll*a*k-b;
		if ((x<0&&y>0)||(x>0&&y<0)){
			printf("-1\n");
			continue;
		}
		x=abs(x)%p,y=abs(y)%p;
		int c=1ll*x*mlt(y,p-2,p)%p;
		int Ans=BSGS(a,c,p);
		printf(!~Ans?"-1\n":"%d\n",Ans+1);
	}
	return 0;
}
posted @ 2019-03-30 21:58  Wolfycz  阅读(253)  评论(0编辑  收藏  举报