• BZOJ 2242: [SDOI2011]计算器 BSGS


    这里讲一下普通的 BSGS 如何实现:   

    我们要求解形如 $y^x equiv z(mod p)$ 的 $x$ 的整数解(其中 $gcd(y,p)=1$)   

    我们将 $x$ 写成 $am-b$ 的形式,原式就变为 $y^{am} equiv z imes y^b (mod p)$    

    然后 $b<m$,可以枚举右面所有的取值,然后再枚举左面,整个时间复杂度是 $max(m,frac{p}{m})$    

    然后 $m$ 取到 $sqrt p$ 时时间复杂度是最优的.   

    这道题中要特判一下无解的情况. 

    code: 

    #include <cstdio> 
    #include <map> 
    #include <cstring> 
    #include <cmath>
    #include <algorithm>  
    #define ll long long      
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;  
    int mod; 
    map<int,int>bu;    
    int qpow(int x,int y) 
    { 
        int tmp=1;
        for(;y;y>>=1,x=(ll)x*x%mod) 
            if(y&1) tmp=(ll)tmp*x%mod;
        return tmp; 
    }    
    int exgcd(int a,int b,int &x,int &y) 
    {
        if(!b) { x=1,y=0; return a;}      
        int gcd=exgcd(b,a%b,x,y),tmp=x;     
        x=y,y=tmp-a/b*y;       
        return gcd;    
    }
    void work_1()
    {
        int i,j,x,y;   
        scanf("%d%d%d",&x,&y,&mod);    
        printf("%d
    ",qpow(x,y));    
    }
    void work_2() 
    { 
        int i,j,x,y,z,a,b,c; 
        scanf("%d%d%d",&a,&c,&mod),b=mod;     
        int gcd=exgcd(a,b,x,y);                    
        if(c%gcd||(a==0&&c!=0)) printf("Orz, I cannot find x!
    ");   
        else 
        {
            int t=abs(b/gcd);     
            x=(ll)((ll)x*(c/gcd)%t+t)%t;   
            printf("%d
    ",x);   
        }
    }
    void work_3()
    {         
        int i,j,y,z,m;     
        scanf("%d%d%d",&y,&z,&mod),m=sqrt(mod)+1;    
        if(y%mod==0&&z) 
        {
            printf("Orz, I cannot find x!
    ");
            return;   
        }
        if(z%mod==1) { printf("0
    ");   return ; }   
        bu.clear();     
        int now=z%mod;    
        bu[now]=0;        
        for(i=1;i<m;++i) now=(ll)now*y%mod,bu[now]=i;             
        int f=qpow(y,m);    
        now=1;            
        for(i=1;i<=m+1;++i) 
        {       
            now=(ll)now*f%mod;         
            if(bu.count(now))   
            {
                printf("%d
    ",i*m-bu[now]);     
                return;   
            }            
        }
        printf("Orz, I cannot find x!
    ");  
    }
    int main() 
    { 
        // setIO("input");  
        int i,j,T,x;     
        scanf("%d%d",&T,&x);   
        while(T--) 
        {
            if(x==1) work_1();     
            if(x==2) work_2();   
            if(x==3) work_3();  
        }
        return 0;  
    }
    

      

  • 相关阅读:
    排序算法
    彩票随机6+1,开发实例
    synchronized关键字以及对象锁和类锁的区别
    shell基础
    easyui+Spring MVC+hibernate = 乐途
    easyui + jdbc 实现简单的数据库管理。
    js map
    struts2 using kindeditor upload pictures (including jmagic compressed images)
    easyui filebox 浏览图片
    easyui datagrid to excel
  • 原文地址:https://www.cnblogs.com/guangheli/p/12258391.html
Copyright © 2020-2023  润新知