• POJ 2417


    高次同余方程。   BL == N (mod P)

    求解最小的L。由于数据范围很大,暴力不行

    这里用到baby_step,giant_step算法。意为先小步,后大步。

    令L=i*m+j  (m=ceil(sqrt(p-1))),

    那么原式化为 B^(i*m)*B^j==N(MOD P)————》B^j===N*B^(-i*m)(MOD P)

    我们先预处理B^0,B^1,B^2……B^(m-1),存入HASH表。,这一步就是baby-step,每次移动1

    然后求出B^-m,枚举i,如果存在B^(-i*m)存在于HASH表中,说明存在解L=i*m+j    ,这一步为giant_step,每次移动m

    以上 转 : http://blog.csdn.net/acm_cxlove/article/details/7831793

    此处用的,其实是扩展的算法,不要求P为素数

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int Maxn=65535;
    
    struct hash{
    	int a,b,next;
    }Hash[Maxn*2];
    int flag[Maxn+66];
    int top,idx;
    
    void insert(int a,int b){
    	int k=b&Maxn;
    	if(flag[k]!=idx){
    		flag[k]=idx;
    		Hash[k].next=-1;
    		Hash[k].a=a;
    		Hash[k].b=b;
    		return ;
    	}
    	while(Hash[k].next!=-1){
    		if(Hash[k].b==b) return ;
    		k=Hash[k].next;
    	}
    	Hash[k].next=++top;
    	Hash[top].next=-1;
    	Hash[top].a=a;
    	Hash[top].b=b;
    }
    
    int find(int b){
    	int k=b&Maxn;
    	if(flag[k]!=idx) return -1;
    	while(k!=-1){
    		if(Hash[k].b==b)
    		return Hash[k].a;
    		k=Hash[k].next;
    	}
    	return -1;
    }
    
    int gcd(int a,int b){
    	return b==0? a:gcd(b,a%b);
    }
    
    int ext_gcd(int a,int b,int &x,int &y){
    	int t,ret;
    	if(!b){
    		x=1; y=0;
    		return a;
    	}
    	ret=ext_gcd(b,a%b,x,y);
    	t=x; x=y; y=t-a/b*y;
    	return ret;
    }
    
    int Inval(int a,int b,int n){
    	int x,y,e;
    	ext_gcd(a,n,x,y);
    	e=(long long )x * b%n;
    	return e<0?e+n:e;
    }
    
    int pow_mod(long long a,int b,int c){
    	long long ret=1%c; a%=c;
    	while(b){
    		if(b&1)
    		ret=ret*a%c;
    		a=a*a%c;
    		b=b>>1;
    	}
    	return ret;
    }
    
    int BabyStep(int A,int B,int C){
    	top=Maxn; ++idx;
    	long long buf=1%C,D=buf,K;
    	int i,d=0,tmp;
    	for(i=0;i<=100;buf=buf*A%C,i++){
    		if(buf==B)
    		return i;
    	}
    	while((tmp=gcd(A,C))!=1){
    		if(B%tmp) return -1;
    		++d;
    		C/=tmp;
    		B/=tmp;
    		D=D*A/tmp%C;
    	}
    	int M=(int)ceil(sqrt((double)C));
    	for(buf=1%C,i=0; i<= M; buf=buf*A%C,i++){
    		insert(i,buf);
    	}
    	for(i=0,K=pow_mod((long long )A,M,C);i<=M;D=D*K%C,i++){
    		tmp=Inval((int)D,B,C); int w;
    		if(tmp>=0&&(w=find(tmp))!=-1)
    		return i*M+w+d;
    	}
    	return -1;
    }
    
    int main(){
    	int A,B,C;
    	while(scanf("%d%d%d",&C,&A,&B)!=EOF){
    		B=B%C;
    	//	idx=0;
    		int ans=BabyStep(A,B,C);
    		if(ans==-1) printf("no solution
    ");
    		else printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    C#线程同步lock,Monitor,Mutex,同步事件和等待句柄(1)
    多线程 C#解决方案小结
    10款交互设计原型开发工具
    创建自定义配置节
    禁用外键 oracle
    GUIDESIGNSTUDIO3中文帮助(1)欢迎使用 GUI Design Studio 3.0
    大数据量的数据库设计思考
    gui design studio 3 中文帮助(2)获取帮助
    NHibernate之旅(24):探索NHibernate二级缓存(下)(转)
    客户端原型GUI Design Studio
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3946434.html
Copyright © 2020-2023  润新知