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

73 篇文章 0 订阅
7 篇文章 0 订阅

高次同余方程

题意:求 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;
}

 

 

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

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值