zoukankan      html  css  js  c++  java
  • bsgs总结

    tip:
      bsgs用来求解形如 $B^L == N(mod P)$ 的式子(求解 $L$ )。

    实战:

    T1:Discrete Logging(板子)

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<map>
     5 #define ll long long
     6 using namespace std;
     7 ll a,b,mod,m,ans,s,judge;
     8 map< ll,int > v;
     9 inline ll qpow(ll a,ll x,ll sum=1){
    10     for(;x;x>>=1,a=a*a%mod) if(x&1) sum=sum*a%mod;
    11     return sum;
    12 }
    13 signed main(){
    14     while(~scanf("%lld%lld%lld",&mod,&a,&b)){
    15         v.clear();
    16         if(a%mod==0){    puts("no solution"); continue;    }
    17         m=sqrt(mod)+1;  ans=b%mod;
    18         for(register int i=1;i<=m;++i){    ans=(ans*a)%mod; v[ans]=i;    }
    19         s=qpow(a,m); ans=1; judge=0;
    20         for(register int i=1;i<=m;++i){
    21             ans=(ans*s)%mod; 
    22             if(v[ans]){
    23                 ll t=(i*m-v[ans]+mod)%mod;
    24                 printf("%lld
    ",(i*m%mod-v[ans]+mod)%mod);
    25                 judge=1; break;
    26             }
    27         }
    28         if(judge==0) puts("no solution");
    29     }
    30 }

    T2:计算器

    题干:
      你被要求设计一个计算器完成以下三项任务:
      1、给定y,z,p,计算 $Y^Z mod P $ 的值;
      2、给定y,z,p,计算满足 $ xy ≡ Z ( mod P ) $的最小非负整数
      3、给定y,z,p,计算满足 $ Y^x ≡ Z ( mod P) $的最小非负整数

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<map>
     5 #define ll long long
     6 using namespace std;
     7 ll m,n,k,t,x,T,y,z,mod;
     8 inline int qpow(ll a,ll x,ll mod,ll sum=1){
     9     for(;x;x>>=1,a=a*a%mod) if(x&1) sum=sum*a%mod;
    10     return sum;
    11 }
    12 inline ll exgcd(ll a,ll b,ll &x,ll &y){
    13     if(b==0){    x=z/a; y=0; return a;    }
    14     ll ans=exgcd(b,a%b,y,x);
    15     y-=a/b*x;
    16     return ans;
    17 }
    18 inline void bsgs(ll a,ll b,ll mod){
    19     //printf("%lld %lld %lld
    ",a,b,mod);
    20     map< ll,ll > v;
    21     if(a%mod==0){    puts("Orz, I cannot find x!"); return;    }
    22     ll maxx=sqrt(mod)+1,judge=0,s=qpow(a,maxx,mod),ans=b%mod;
    23     for(register int i=1;i<=maxx;++i)  ans=(ans*a)%mod, v[ans]=i;
    24     ans=1;
    25     for(register int i=1;i<=maxx;++i){
    26         ans=(ans*s)%mod; 
    27         if(v[ans]){
    28             printf("%lld
    ",(i*maxx%mod-v[ans]+mod)%mod);
    29             judge=1; break;
    30         }
    31     }
    32     if(judge==0) puts("Orz, I cannot find x!");
    33 }
    34 inline void work(){
    35     scanf("%lld%lld%lld",&y,&z,&x);
    36     if(k==1) printf("%d
    ",qpow(y,z,x));
    37     if(k==2){
    38         ll xx,yy,gcd=exgcd(y,x,xx,yy);
    39         if(z%gcd) puts("Orz, I cannot find x!");
    40         else{
    41             xx%=x;
    42             (xx<0)?printf("%lld
    ",xx+x):printf("%lld
    ",xx);
    43         }
    44     }
    45     if(k==3) bsgs(y,z,x);
    46 }
    47 signed main(){
    48     scanf("%lld%lld",&T,&k);
    49     while(T--) work();
    50 }
    View Code

    T3:Matrix

    题干:

      给定矩阵 A , B 和模数 p ,求最小的 x 满足 $A^x = B (mod p)$,数据保证在p内有解

    题解:
      这道题就是注意矩阵定义时注意重载运算符 < 。

    Code:

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cstdlib>
     4 #include<cmath>
     5 #include<map>
     6 #define $ 72
     7 using namespace std;
     8 int m,n,mod;
     9 struct tree{
    10     int a[$][$];
    11     tree(){    memset(a,0,sizeof(a));    }
    12     friend bool operator < (tree aa,tree bb){
    13         for(register int i=1;i<=n;++i)
    14             for(register int j=1;j<=n;++j){
    15                 if(aa.a[i][j]!=bb.a[i][j])  return aa.a[i][j]<bb.a[i][j];
    16             }
    17         return 0;
    18     }
    19     friend tree operator * (tree aa,tree bb){
    20         tree sum=tree();
    21         for(register int i=1;i<=n;++i)
    22             for(register int j=1;j<=n;++j)
    23                 for(register int k=1;k<=n;++k)
    24                     sum.a[i][j]=(sum.a[i][j]+aa.a[i][k]*bb.a[k][j])%mod;
    25         return sum;
    26     }
    27     friend tree operator ^ (tree aa,int x){
    28         tree sum=tree();
    29         for(register int i=1;i<=n;++i) sum.a[i][i]=1;
    30         for(;x;x>>=1,aa=aa*aa) if(x&1) sum=sum*aa;
    31         return sum;
    32     }
    33 }A,B;
    34 map< tree,int > v;
    35 inline void bsgs(){
    36     int maxx=sqrt(mod)+1;
    37     tree ans=B,s=A^maxx;
    38     for(register int i=1;i<=maxx;++i) ans=ans*A, v[ans]=i;
    39     for(register int i=1;i<=n;++i) ans.a[i][i]=1;
    40     ans=tree();
    41     for(register int i=1;i<=n;++i) ans.a[i][i]=1;
    42     for(register int i=1;i<=maxx;++i){
    43         ans=ans*s;
    44         if(v[ans]) printf("%d
    ",(i*maxx%mod-v[ans]+mod)%mod), exit(0);
    45     }
    46     puts("Orz Orz Orz Orz Orz Orz Orz Orz Orz Orz");
    47 }
    48 signed main(){
    49     scanf("%d%d",&n,&mod);
    50     for(register int i=1;i<=n;++i)
    51         for(register int j=1;j<=n;++j)  scanf("%d",&A.a[i][j]);
    52     for(register int i=1;i<=n;++i)
    53         for(register int j=1;j<=n;++j)    scanf("%d",&B.a[i][j]);
    54     bsgs();
    55 }
    View Code
    越努力 越幸运
  • 相关阅读:
    erl_0012 timer:tc 测试模块函数调用运行耗时
    erl_0011 erlang 定时器相关
    erl0010
    erl0009
    erl0008
    erl0007
    erl0006
    erl0005
    开开心心过生活、踏踏实实做技术
    Android-理解Intent
  • 原文地址:https://www.cnblogs.com/OI-zzyy/p/11235623.html
Copyright © 2011-2022 走看看