码迷,mamicode.com
首页 > 其他好文 > 详细

uva 1426 - Discrete Square Roots(拓展欧几里得)

时间:2014-07-06 00:11:14      阅读:268      评论:0      收藏:0      [点我收藏+]

标签:style   http   color   width   os   for   

题目链接:uva 1426 - Discrete Square Roots

题目大意:给出X,N,R,求出所有满足的r,使得r2x%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;
}

uva 1426 - Discrete Square Roots(拓展欧几里得),布布扣,bubuko.com

uva 1426 - Discrete Square Roots(拓展欧几里得)

标签:style   http   color   width   os   for   

原文地址:http://blog.csdn.net/keshuai19940722/article/details/36931617

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!