bsgs总结

Posted oi-zzyy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",(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\n",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\n",(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\n",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\n",xx+x):printf("%lld\n",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\n",(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

以上是关于bsgs总结的主要内容,如果未能解决你的问题,请参考以下文章

任务表(知识总结)

二次剩余(懒人模板总结)

二次剩余(懒人模板总结)

0301考试总结

第十五届吉林省赛The 15th Jilin Provincial Collegiate Programming Contest C.Random Number Generator(数学 BSGS)

第十五届吉林省赛The 15th Jilin Provincial Collegiate Programming Contest C.Random Number Generator(数学 BSGS)