bzoj 3122: [Sdoi2013]随机数生成器【BSGS】

题目要求的是:

\[...a(a(a(ax+b)+b)+b)+b...=a^nx+a^{n-1}b+a^{n-2}b+...+b\equiv t(mod\ p) \]

后面这一大坨看着不舒服,所以考虑把它化掉,这里有两种做法:

做法一:两边同乘a-1

\[(a^{n-1}x)(a-1)+b(a^{n-1}-1)\equiv t(a-1)(mod\ p) \]

\[a^nx-a^{n-1}x+ba^{n-1}-b \equiv at-t(mod\ p) \]

\[axa^{n-1}-xa^{a-1}+ba^{n-1} \equiv at-t+b(mod\ p) \]

\[(ax-x+b)a^{n-1} \equiv at-t+b(mod\ p) \]

\[a^{n-1}\equiv (at-t+b)inv(ax-x+b)(mod\ p) \]

注意这个很容易乘爆,记得随时取模

做法二:后面乘上a-1的逆元

\[a^{n-1}x+b(a^{n-1}-1)inv(a-1)\equiv t(mod\ p) \]

\[a^{n-1}x+b*a^{n-1}*inv(a-1)-b*inv(a-1)\equiv t(mod\ p) \]

\[a^{n-1}x+b*a^{n-1}*inv(a-1)\equiv t+b*inv(a-1)(mod\ p) \]

\[a^{n-1}(b*inv(a-1)+x)\equiv t+b*inv(a-1)(mod\ p) \]

\[a^{n-1}\equiv (t+b*inv(a-1))inv(b*inv(a-1)+x)(mod\ p) \]

然后用BSGS解即可,记得加一

#include<iostream>
#include<cstdio>
#include<map>
#include<cmath>
using namespace std;
long long T,p,a,b,x,t,y,z;
map<long long,long long>mp;
long long ksm(long long a,long long b)
{
	long long r=1ll;
	a%=p;
	while(b)
	{
		if(b&1)
			r=r*a%p;
		a=a*a%p;
		b>>=1;
	}
	return r;
}
int main()
{
	scanf("%lld",&T);
	while(T--)
	{
		scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x,&t);
		if(x==t)
		{
			puts("1");
			continue;
		}
		if(a==0)
		{
			if(b==t)
				puts("2");
			else
				puts("-1");
			continue;
		}
		if(a==1&&b==0)
		{
			puts("-1");
			continue;
		}
		if(a==1)
		{
			long long now=ksm(b,p-2);
			printf("%lld\n",(((t-x)%p+p)%p*now%p+p)%p+1);
			continue;
		}
		y=a,z=((a*t%p-t+b)%p*ksm(a*x-x+b,p-2)%p+p)%p;
		//y=a,z=((t+b*ksm(a-1,p-2)%p)%p*ksm((x%p+b*ksm(a-1,p-2)%p)%p,p-2))%p;//(a*t-t+b)*ksm(a*x-x+b,p-2);做法二
		y%=p;
		if(!y&&!z)
		{
			puts("1");
			continue;
		}
		if(!y)
		{
			puts("-1");
			continue;
		} 
		mp.clear();
		long long m=ceil(sqrt(p)),t=1;
		mp[1]=m+1;
		for(long long i=1;i<m;i++)
		{
			t=t*y%p;
			if(!mp[t])
				mp[t]=i;
		}
		long long tmp=ksm(y,p-m-1),now=1,f=0;
		for(long long k=0;k<m;k++)
		{
			long long i=mp[z*now%p];
			if(i) 
			{
				if(i==m+1)
					i=0;
				printf("%lld\n",k*m+i+1);
				f=1;
				break;
			}
			now=now*tmp%p;
		}
		if(!f)
			puts("-1");
	}
	return 0;
}
posted @ 2018-01-26 16:21  lokiii  阅读(170)  评论(0编辑  收藏  举报