【暖*墟】 #数论# 高次同余方程

版权声明:本文为博主原创文章,未经博主允许不得转载qwq。https://blog.csdn.net/flora715 https://blog.csdn.net/flora715/article/details/82378931

高次同余方程

题意:求 A^x = B (mod P) 的解,其中A、P互质。


【思路分析】

因为a、p互质,所以可以在模p意义下执行关于a的乘除法运算。

t=[√p(下取整)],将 x 转化为:x=i*t-j

则方程变为:a^(i*t-j)=b (mod p),即 (a^t)^i=b*(a^j) (mod p)

所以,对于所有的 j 属于[0,t-1],把 b*(a^j) (mod p) 插入一个 Hash 表。

枚举所有可能 i,计算 (a^t)^i (mod p),在 Hash 表中寻找是否有匹配值。


【相关代码实现】

//Baby Step, Giant Step算法
//同余方程 a^x mod p = b,求x的最小非负整数解,无解返回-1

int baby_step_giant_step(int a, int b, int p){

    map<int, int> hash; hash.clear(); 
    b%=p; int t=(int)sqrt(p)+1; //t=[√p(下取整)]+1,时间复杂度最优

    for(int j=0;j<=t-1;j++){ //对于j属于[0,t-1]
    	int val=(long long)b*power(a,j,p)%p;
		hash[val] = j; //把b*(a^j) (mod p)插入一个Hash表。
	}

    a=power(a,t,p); //预处理出a^t
    if(a==0) return b==0?1:-1; //特判
    for(int i=0;i<=t;i++){ //枚举所有可能i,计算(a^t)^i (mod p)
    	int val=power(a,i,p); //(a^t)^i
        int j=hash.find(val)==hash.end() ? -1:hash[val];
        //↑↑↑map中的find函数,返回位置指针。如果有,j=hash[val]。
        if(j>=0&&i*t-j>=0) return i*t-j; //x=i*t-j
    }

    return -1;
}

其中的power算法用快速幂实现(注意longlong的使用)。

ll power(ll a,ll b,ll m){ //求a的b次方%m
    ll ans=1; //ans为答案
    while(b>0){ //b是不断右移的二进制数
        if(b&1) //&是位运算,b&1表示b在二进制下最后一位是不是1,如果是:
            ans=(ll)ans*a%m; //把ans乘上对应的a^(2^i)
        a=(ll)a*a%m; //a自乘,由a^(2^i)变成a^(2^(i+1))
        b>>=1; //位运算,b右移一位
    }
    return ans;
}

                                                     ——时间划过风的轨迹,那个少年,还在等你。

猜你喜欢

转载自blog.csdn.net/flora715/article/details/82378931
今日推荐