• BSGS&ExBSGS


    BSGS&ExBSGS

    求解形如

    [a^xequiv bpmod p ]

    的高次同余方程

    BSGS

    假装(gcd(a,p)=1)

    (m=lceilsqrt p ceil)

    然后把(x)分解成

    [x=i*m+j ]

    的形式。

    [a^xequiv bpmod p ]

    [a^{i*m+j}equiv bpmod p ]

    [a^{im}equiv b/a^jpmod p ]

    这时我们发现,(1≤j≤m-1),也就是说枚举(j)是非常简单的。

    这样我们就可以把(m-1)(j)全都存起来,存到哈希表中,然后枚举(i),这样就可以在(O(sqrt n + log (n)))的时间内求出解了。(分块 + map)

    (时间复杂度是wyh在网上找的,自己不会证qwq

    ExBSGS

    刚刚我们假装(gcd(a,p)=1),那要是没有这个条件怎么办呢?

    很简单,我们只要通过把两边同时除以 他们的 gcd 就好啦qwq

    (g=gcd(a,p)),如果(g ot| b),显然如果(p=1)(x=0),否则方程无解

    我们就得到

    [a^{x-1}*frac{a}{g}equiv frac{b}{g}pmod {frac{p}{g}} ]

    [a^{x-1}equiv frac{b}{a}pmod {frac{p}{g}} ]

    这样一直做下去,直到(g=1)为止。

    有一个误区(对于我这种蒟蒻)就是(a)(b/g)不一定互质。这是zzy学长告诉wyh的qwq,还是学长好啊qwq。

    好感动啊。。。

    Code

    
    typedef long long ll;
    map<ll,ll> ma;
    inline ll bsgs(ll a,ll b)//解a^x同余b (%mod) 
    {
    	a%=mod;b%=mod;
    	ma.clear();
    	ll m=ll(sqrt(mod+1)),e=1;
    	for(int j=0;j<m;++j)
    	{
    		if(!ma.count(e)) ma[e]=j;
    		e=e*a%mod;
    	}
    	if(gcd(e,mod)!=1) return -1;
    	ll inv=inverse(e);//逆元 
    	for(int i=0;i<m;++i)
    	{
    		if(ma.count(b)) return i*m+ma[b];
    		b=b*inv%mod;
    	}
    	return -1;
    }
    
    
  • 相关阅读:
    test
    flash链接需要后台调用时的插入flash方法
    js验证码倒计时
    设置Cookie
    用in判断input中的placeholder属性是否在这个对象里
    常用的正则表达式规则
    webApp添加到iOS桌面
    .substr()在字符串每个字母前面加上一个1
    PAT 甲级1001 A+B Format (20)(C++ -思路)
    PAT 1012 数字分类 (20)(代码+测试点)
  • 原文地址:https://www.cnblogs.com/oierwyh/p/11375107.html
Copyright © 2020-2023  润新知