【POJ 3243】Clever Y 拓展BSGS

调了一周,我真制杖,,,

各种初始化没有设为1,,,我当时到底在想什么???

拓展BSGS,这是zky学长讲课的课件截屏:

是不是简单易懂。PS:聪哥说“拓展BSGS是偏题,省选不会考,信我没错”,那是因为聪哥早就会了,所以他觉得学这个没用,信他才怪233

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
LL A,B,C;
struct node{
	static const int mo=100007;
	LL a[mo],v[mo];
	void clear() {memset(a,-1,sizeof(a));}
	LL find(LL val){
		LL pos=(val%mo+mo)%mo;
		while ((a[pos]!=val)&&(a[pos]!=-1)) pos=(pos+1)%mo;
		return pos;
	}
	void insert(int val,int x){
		LL pos=find(val);
		if ((a[pos]==-1)||(a[pos]==val)){
			a[pos]=val; v[pos]=x;
		}
	}
	LL get(LL val){
		LL pos=find(val);
		return a[pos]==val?v[pos]:-1;
	}
}hash;
LL gcd(LL x,LL y) {LL r=x%y; while (r!=0){x=y; y=r; r=x%y;} return y;}
void exgcd(LL aa,LL bb,LL &x, LL&y){
	if (bb==0){
		x=1; y=0; return;
	}
	exgcd(bb,aa%bb,x,y);
	LL t=y;
	y=x-aa/bb*y;
	x=t;
}
LL ni(LL a,LL b){
	LL x,y;
	exgcd(a,b,x,y);
	return (x+C)%C;
}
LL ipow(LL a,LL b,LL c){
	LL ans=1,t=a;
	while (b){
		if (b%2==1) ans=(ans*t)%c;
		t=(t*t)%C; b/=2;
	}
	return ans;
}
void bsgs(){
	B%=C;
	if (B==1) {puts("0"); return;}
	else if ((A==0)&&(B==0)) {puts("1"); return;}
	else if (B==0) {puts("No Solution"); return;}
	LL t=1;
	for(LL i=0;i<=50;++i){
		if (t==B){
			printf("%I64d\n",i);
			return;
		}
		t=(t*A)%C;
	}
	LL g,ans1=0,D=1;
	while ((g=gcd(A,C))!=1){
		if (B%g){
			puts("No Solution");
			return;
		}
		++ans1;
		B/=g;
		C/=g;
		D=(A/g*D)%C;
	}
	D=ni(D,C);
	LL m=ceil(sqrt((double)C));
	hash.clear();
	t=B*D%C;
	for(LL i=0;i<=m;++i){
		hash.insert(t,i);
		t=(t*A)%C;
	}
	LL basic=ipow(A,m,C);
	t=1;
	for(LL i=0;i<=m;++i){
		int x=hash.get(t);
		if (x!=-1){
			printf("%I64d\n",ans1+i*m-x);
			return;
		}
		t=(t*basic)%C;
	}
	puts("No Solution");
}
int main(){
	while (scanf("%I64d %I64d %I64d\n",&A,&C,&B)){
		if ((A==0)&&(B==0)&&(C==0)) break;
		bsgs();
	}
	return 0;
}

这样就可以啦

posted @ 2016-03-19 22:21  abclzr  阅读(264)  评论(0编辑  收藏  举报