zoukankan      html  css  js  c++  java
  • BZOJ 5296: [Cqoi2018]破解D-H协议(BSGS)

    传送门

    解题思路

      (BSGS)裸题??要求的是(g^a =A (mod) (p)),设(m)(sqrt p),那么可以设(a=i*m-j),式子变成
      $$ g^{i*m-j}=Amod p$$
      然后把(j)移过去,
      $$g{i*m}=A*gjmod p$$

      然后可以预处理枚举(j)的值用哈希存下来,每次直接(O(m))询问,总的时间复杂度为(O(Tsqrt p log))

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<map>
    #include<set>
    #define int long long
    
    using namespace std;
    typedef long long LL;
    
    int g,MOD,T,A,B,a,b,m;
    map<int,int> mp;
    
    inline int fast_pow(int x,int y){
    	int ret=1;
    	for(;y;y>>=1){
    		if(y&1) ret=1ll*ret*x%MOD;
    		x=1ll*x*x%MOD;
    	}
    	return ret;
    }
    
    inline void prework(){
    	m=ceil(sqrt(MOD));
    	int base=fast_pow(g,m),now=1;
    	mp[now]=0;
    	for(int i=1;i<=m;i++){
    		now=1ll*now*base%MOD;
    		mp[now]=i;
    	}
    }
    
    inline int BSGS(int x){
    	int now=x;
    	if(mp.count(now)) return mp[now]*m;
    	for(int i=1;i<=m;i++){
    		now=1ll*now*g%MOD;
    		if(mp.count(now)) return mp[now]*m-i;
    	}
    }
    
    signed main(){
    	scanf("%lld%lld%lld",&g,&MOD,&T);
    	prework();
    	while(T--){
    		scanf("%lld%lld",&A,&B);
    		a=BSGS(A); b=BSGS(B);
     		a=(a%(MOD-1)+MOD-1)%(MOD-1);
    		b=(b%(MOD-1)+MOD-1)%(MOD-1);
    		printf("%lld
    ",fast_pow(g,1ll*a*b%(MOD-1)));
    	}
    	return 0;
    }	
    
  • 相关阅读:
    蓝桥杯_基础训练_龟兔赛跑预测
    大数加法
    Splay!
    topsort
    各种方法
    有时候dfs可以简化各种组合的操作
    组合数学
    重新认识三观
    手速狗还是不行啊。。。
    set和map和pair 转自ACdreamers
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10415014.html
Copyright © 2011-2022 走看看