ACM学习历程—HDU5478 Can you find it(数论)(2015上海网赛11题)

Problem Description

Given a prime number C(1≤C≤2×105), and three integers k1, b1, k2 (1≤k1,k2,b1≤109). Please find all pairs (a, b) which satisfied the equation a^(k1⋅n+b1 )+ b^(k2⋅n−k2+1) = 0 (mod C)(n = 1, 2, 3, ...).

 

 

Input

There are multiple test cases (no more than 30). For each test, a single line contains four integers C, k1, b1, k2.

 

 

Output

First, please output "Case #k: ", k is the number of test case. See sample output for more detail.
Please output all pairs (a, b) in lexicographical order. (1≤a,b<C). If there is not a pair (a, b), please output -1.

 

 

Sample Input

23 1 1 2

 

 

Sample Output

Case #1:

1 22

题目意思一开始理解错了,然后以为只要能找到一个n满足条件,这组(a, b)就算满足条件。

原来是要所有n满足才行,这样题目就是任意型问题,相对会好解决一点。

既然是任意,肯定考虑先取些特殊值试试。

自然考虑取n=1,

发现a^(k1+b1) + b = 0(mod c)

这样就把b在模c情况下的值求出来了。

b = - a^(k1+b1)(mod c)

然后继续带入n = 2,

a^(2k1+b1) + b^(k2+1) = 0(mod c)

大胆猜测这个式子成立,n取任何数都会成立。

因为n加1时,a的指数和b的指数增量是一定的,那么n取任何数时,必然和n-1之前相差的式子是一个定值多项式。

首先n = 2时,

可以得到b^(k2+1) = -a^(2k1+b1) = -a^(k1+b1)*a^k1 = b*a^k1

这一步可以通过n = 1得到的结论两边消掉一个b,得:

b^k2 = a^k1。

也就是说由n = 1满足,让n = 2满足的条件是b^k2 = a^k1。

基本是可以YY一下,由n = 2满足,让n = 3满足的条件是b^k2 = a^k1。

即由n = k满足,让n = k+1满足的条件是b^k2 = a^k1。

这一步用数学归纳法随便搞一搞就可以验证了。

不知道是什么情况,比赛时是n = 1得出b, n = 2验证b过的。

现在重写了一遍死活T。。。

后来换成n = 2时验证式子b^k2 = a^k1就能过了。。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <string>
#define LL long long

using namespace std;

int c, k1, b1, k2;

//快速幂m^n
LL quickPow(LL x, LL n)
{
    LL a = 1;
    while (n)
    {
        a *= n&1 ? x : 1;
        a %= c;
        n >>= 1;
        x *= x;
        x %= c;
    }
    return a;
}

bool judge(LL a, LL b)
{
    if (quickPow(a, k1) != quickPow(b, k2))
        return false;
    else
        return true;
}

void work()
{
    LL b;
    bool flag = false;
    for (int a = 1; a < c; ++a)
    {
        b = -quickPow(a, (b1+k1)%(c-1));
        b = (b+c)%c;
        if (judge(a, b))
        {
            printf("%d %I64d
", a, b);
            flag = true;
        }
    }
    if (!flag)
        printf("-1
");
}

int main()
{
    //freopen("test.in", "r", stdin);
    int times = 1;
    while (scanf("%d%d%d%d", &c, &k1, &b1, &k2) != EOF)
    {
        printf("Case #%d:
", times);
        work();
        times++;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/andyqsmart/p/4857536.html