zoukankan      html  css  js  c++  java
  • 浅谈BSGS

    用于求解形如(a^x≡bmod p)的最小非负整数解(x).

    由欧拉定理(a^{phi(p)}≡1mod p)可以知道,我们找的解如果有解则一定在(phi(p))范围内,而最大的范围就是当(p)为质数时,等于(p-1).

    一种暴力方法是枚举指数验证。由于(gcd(a,p)=1).则(a)(mod p)意义下必有逆元。所以,我们考虑分解一下质数的表示形式。

    知道最大范围不超过(p),所以我们令(x=i*m-j),将(a^{-j})移项到左边,变成(a^{i*m}≡b*a^jmod p).这里(m=lceil{sqrt{p}} ceil).

    我们枚举(b*a^j),把它们(mod p)的值插入到( ext{Hash})表里面。我们再枚举(a^{i*m}),如果这个值在( ext{Hash})表里面出现过,则跳出循环,输出答案。

    特判无解,一是没有找到解,另一个是无解,即(amod p=0,b!=0),或是(a=0)的时候。(就那几个特殊情况)

    这就是(BSGS)的基本思路。下面是( ext{fast_power,Exgcd,BSGS})的三合一模板。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define int long long
    int mul(int a,int b,int p){return (1ll*a*b)%p;}
    int add(int a,int b,int p){return (1ll*a+b)%p;}
    int qpow(int a,int b,int p){
    	int res=1;
    	while(b){
    		if(b&1)res=mul(res,a,p);
    		a=mul(a,a,p);b>>=1;
    	}
    	return res;
    }
    int Exgcd(int a,int b,int &x,int &y){
    	if(!b){x=1,y=0;return a;}
    	int res=Exgcd(b,a%b,x,y);
    	int tmp=x;x=y;y=tmp-a/b*y;
    	return res;
    }
    map<ll,ll>mp;
    int T,opt;
    signed main(){
    	scanf("%lld%lld",&T,&opt);
    	for(;T;--T){
    		int y,z,p;
    		scanf("%lld%lld%lld",&y,&z,&p);
    		if(opt==1)printf("%lld
    ",qpow(y,z,p));
    		else if(opt==2){
    			int x,yy;
    			int G=Exgcd(y,p,x,yy);
    			if(z%G){puts("Orz, I cannot find x!");continue;}
    			int tmp=p/G;while(x<0)x+=tmp;
    			printf("%lld
    ",((x*z/G)%tmp+tmp)%tmp);
    		}
    		else{
    			mp.clear();
    			if(y%p==0&&z){puts("Orz, I cannot find x!");continue;}
    			int m=ceil(sqrt(p)),f=qpow(y,m,p),now=z%p;
    			for(int i=1;i<=m;++i)now=mul(now,y,p),mp[now]=i;
    			now=1;int flag=1;
    			for(int i=1;i<=m;++i){
    				now=mul(now,f,p);
    				if(mp[now]){
    					int ans=add(mul(i,m,p),-mp[now],p);
    					printf("%lld
    ",add(ans,p,p));
    					flag=0;break;
    				}
    			}
    			if(flag)puts("Orz, I cannot find x!");
    		}
    	}
    	return 0;
    } 
    

    ( ext{Hash})使用了( ext{map}).

    时间复杂度(O(sqrt{phi(p)})),非扩展(BSGS)适用于(p)为质数情况。(gcd(p,a)=1).

  • 相关阅读:
    机器学习-好讲解
    caffe-BN层
    所有子文件夹中图片个数matlab代码实现
    17.5.11 自己领悟
    ubuntu16.04初始安装+无gpu+caffe+python2+opencv2+matlab2016+tensorflow
    No module named caffe
    Ubuntu14.04_64位使用过程
    Ubuntu14 sudo apt-get install apt-show-versions出错
    Active MQ 传输 ObjectMessage 异常
    spring 在静态工具类中使用注解注入bean
  • 原文地址:https://www.cnblogs.com/h-lka/p/12686980.html
Copyright © 2011-2022 走看看