您的位置:首页 > 产品设计 > UI/UE

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

2018-02-02 11:17 561 查看
题目连接 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  逆元
相关文章推荐