zoukankan      html  css  js  c++  java
  • 【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
    ",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
    ",ans1+i*m-x);
    			return;
    		}
    		t=(t*basic)%C;
    	}
    	puts("No Solution");
    }
    int main(){
    	while (scanf("%I64d %I64d %I64d
    ",&A,&C,&B)){
    		if ((A==0)&&(B==0)&&(C==0)) break;
    		bsgs();
    	}
    	return 0;
    }
    

    这样就可以啦

  • 相关阅读:
    OAuth2.0协议流程
    记多个微服务同时被kill分析
    记一次调用API遇到的问题
    win10安装mysql遇到的坑
    nagios
    rmp安装mysql5.6
    桥接模式-xshell连接虚拟机
    VMWare虚拟机-网络适配器
    ***时间目录***
    docker常用命令
  • 原文地址:https://www.cnblogs.com/abclzr/p/5296572.html
Copyright © 2011-2022 走看看