【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; }
这样就可以啦
NOI 2017 Bless All