bzo j3122: [Sdoi2013]随机数生成器

这道题不难想,难的是分类讨论。

先是最一般的情况

推出公式套用bsgs。 这个要求答案>1且a!=1(等比数列的分类讨论)且a!=0(0没有逆元)

所以第一种情况a!=1 a!=0 ans=1

第二种情况 a!=1 a!=0 ans!=1

如果a=1,第一种情况ans=1

第二种情况 ans!=1 b=0 (0没有逆元)

第三种情况 ans!=1 b!=0

如果a=0,

a1=t 则ans=1 

否则b=t ans=2

否则无解。

共8种情况。

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>

#define ll long long
#define inf 1e9
#define eps 1e-10
#define md
#define H 500000
#define N 100010
using namespace std;
struct yts { int a,is,ne;};
struct ha
{
	int v[H];
	yts e[N];
	int cnt; 
	void clear()
	{
		memset(v,0,sizeof(v));
		cnt=0;
	}
	void insert(ll a,int is)
	{
		int x=a%H,i;
		for (i=v[x];i;i=e[i].ne)
		  if (e[i].a==a) break;
		if(!i)
		{
			i=++cnt; e[i].a=a; e[i].is=is;
			e[i].ne=v[x]; v[x]=i;
		}
	}
	int find(ll a)
	{
		int x=a%H,i;
		for (i=v[x];i;i=e[i].ne)
		  if (e[i].a==a) break;
		if (i) return e[i].is;
		  else return -1;
	}
} hash; 
		
	

ll kpow(ll a,int b,int p)
{
	ll ans=1;
	while (b)
	{
		if (b&1) ans=ans*a%p;
		a=a*a%p; b>>=1;
	}
	return ans;
}

void bsgs(ll a,ll b,int p)
{
	//printf("bsgs %lld %lld %d\n",a,b,p);
	hash.clear();
	int m=sqrt(a);
	ll ji=b,cheng=kpow(a,p-2,p);
	for (int i=0;i<m;i++)
	{
		hash.insert(ji,i);
		ji=ji*cheng%p;
	}
	ji=1; cheng=kpow(a,m,p);
	for (int i=0;i<p;i+=m)
	{
		int x=hash.find(ji);
		if (x!=-1) { printf("%d\n",x+i+1); return;}
		ji=ji*cheng%p;
	}
	printf("-1\n");
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("data.in","r",stdin); freopen("data.out","w",stdout);
#endif
	int tt;
	scanf("%d",&tt);
	while (tt--)
	{
		int p; ll a,b,x1,t;
		scanf("%d%lld%lld%lld%lld",&p,&a,&b,&x1,&t);
		if (a==0)
		{
			if (x1==t) printf("1\n");
			else if (t==b) printf("2\n");
			else printf("-1\n");
		}
		else if (a==1)
		{
			if (t==x1) printf("1\n");
			else
			{
				if (b==0) printf("-1\n");
				else
				{
					ll x=(t-x1+b+p)%p; x=x*kpow(b,p-2,p)%p;
					if (x==0) printf("%d\n",p);
					  else printf("%lld\n",x);
				}
			}
		}
		else
		{
			if (t==x1) printf("1\n");
			else
			{
				ll x=((a-1)*t+b)%p,y=((a-1)*x1+b)%p;
				x=x*kpow(y,p-2,p)%p;
				bsgs(a,x,p);
			}
		}
	}
}


你可能感兴趣的:(数论,分类讨论,BSGS)