Educational Codeforces Round 37 (Rated for Div. 2) E. Congruence Equation

  • 题目连接 http://codeforces.com/group/1EzrFFyOc0/contest/919/problem/E
  • 算法:逆元公式推导,变换
    • (1)
    • 令 n = i*(p-1)+ j (2)
    • 得 (i*(p-1)+j)a^(i(p-1)) 三 b*a^(-j) (3)
      - a^(-j) 可通过求 a^j 的逆元求得
    • 令(3)式右边等于 y,对(3)两边取模,与(1)联立
      • 得 i = j-y
      • 遍历 j (1<= j <= p-1),通过(2)式可求得 对于当前 j 的第一个 满足等式的n
      • 又因为 a的指数n 每p-1次一个循环,a的系数n每p次一个循环,所以总循环为 p(p-1) 一个循环,即得ans

#include <bits/stdc++.h>
#define pi acos(-1)
using namespace std;
typedef long long LL;
typedef pair<int, int> Pii;
const int INF = 0x3f3f3f3f;
const LL ll_INF = 0x3f3f3f3f3f3f3f3f;//4e18 ~= 2^62
const int N =300000 + 10;
const LL mod = 1e9+7;
LL a, b, p, x, n, ans=0;

LL pow(LL a, LL n, LL p)    // 快速幂
{
    LL ans = 1;
    while(n)
    {
        if(n & 1) ans = ans * a % p;
        a = a * a % p;
        n >>= 1;
    }
    return ans;
}

LL inv(LL x, LL p)    // 求逆元
{
    return pow(x, p-2, p);
}

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    cin >> a >> b >> p >> x;
    for(LL j=1; j<=p-1; j++){
        LL y= b*inv(pow(a, j, p), p)%p;
        LL first = (p-1)*((j-y+p)%p)+j;
        if(first>x) continue;
        ans+=(x-first)/(p*(p-1LL))+1LL;
    }
    cout << ans << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值