首页 > 代码库 > uva 1426 - Discrete Square Roots(拓展欧几里得)
uva 1426 - Discrete Square Roots(拓展欧几里得)
题目链接:uva 1426 - Discrete Square Roots
题目大意:给出X,N,R,求出所有满足的r,使得r2≡x%N,并且R是一个其中的解。
解题思路:
- R2?r2=k?N
- (R?r)(R+r)=k?N
- => aA=(R+r),bB=(R?r),A,B为N的因子
所以枚举A,B,就有r=R?aA=bB?R - aA+bB=2?R
拓展欧几里得求解,将所有满足的解放入set中自动去重。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <algorithm>
using namespace std;
typedef long long ll;
ll X, N, R;
set<ll> ans;
void exgcd (ll a, ll b, ll& d, ll& x, ll& y) {
if (b == 0) {
d = a;
x = 1;
y = 0;
} else {
exgcd (b, a%b, d, y, x);
y -= (a/b) * x;
}
}
void solve (ll A, ll B, ll C) {
ll d, x, y;
exgcd(A, B, d, x, y);
if (C % d)
return;
x = x * C / d;
x = (x % (B/d) + (B/d))%(B/d);
ll s = x * A - C / 2;
ll k = A * B / d;
for (ll i = s; i < N; i += k)
if (i >= 0)
ans.insert(i);
}
int main () {
int cas = 1;
while (scanf("%lld%lld%lld", &X, &N, &R) == 3 && X + N + R) {
ans.clear();
ll m = sqrt(N+0.5);
for (ll i = 1; i <= m; i++) {
if (N%i)
continue;
solve(i, N/i, 2*R);
solve(N/i, i, 2*R);
}
printf("Case %d:", cas++);
for (set<ll>::iterator i = ans.begin(); i != ans.end(); i++)
printf(" %lld", *i);
printf("\n");
}
return 0;
}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。