您的位置:首页 > 理论基础 > 计算机网络

HDU 5478 Can you find it 2015ICPC上海网络赛

2015-09-27 20:11 633 查看


Can you find it

Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 474 Accepted Submission(s): 219



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 ak1⋅n+b1+ bk2⋅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




Source

2015 ACM/ICPC Asia Regional Shanghai Online



题意:输入C,k1,b1,k2,求满足题中所给公式的所有a,b的值,每对按字典序升序输出。

分析:我们先将公式变一下形为:a^(k1*n) * a^b1 + b^(k2*n) * b^(1-k2)=0(mod C)

(a^k1)^n * a^b1 + (b^k2)^n * b^(1-k2)=0(mod C)

在这个等式中,只有n为未知数,那么就可以看成是两个指数函数和的形式,由于质数函数的导数时刻不同,所以如果要保持在n不同时结果对C取

模仍然等于零的话,那么就要保证底数相同,只有这样他们的增长率才会相同,那么对C取模也就是不变的。这时候我们就可合并同类项了,设

X=a^k1=b^k2,那么公式变形为X*(a^b1+b^(1-k2))%C=0,即b^(1-k2)%C=(C-(a^b1)%C)%C;这是我们就可以进行枚举了,在保证a^k1==b^k2

的前提下枚举其中一个值,然后去验证另外一个值(其实你先枚举符合条件的值然后再进行底数的验证也可以)。现在为了计算方便我们将公式

变形为:(a^k1)^(n-1) * a^(b1+1) + (b^k2)^(n-1) * b=0(mod C) 。然后计算b的时候就能够直接利用C相减了,具体看代码怎么实现的

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#define scnaf scanf
#define cahr char
#define bug puts("bugbugbug");
using namespace std;
typedef long long ll;
const int mod=1000000007;
const int maxn=2000+5;
const int inf=1e9;
const int maxe=200000;
typedef long long ll;
//快速幂
ll pow_mod(ll a, ll n, ll m) {
    ll res = 1;
    while(n) {
        if (n & 1) res = res * a % m;
        n >>= 1;
        a = a * a % m;
    }
    return res;
}
struct T
{
    int a,b;
    bool operator < (const T &c) const {
    if(a!=c.a)
    return a<c.a;
    return b<c.b;
    }
};
vector<T>ans;
int main()
{
    int c,k1,B1,k2,test=1;
    while(~scanf("%d%d%d%d",&c,&k1,&B1,&k2))
    {
        printf("Case #%d:\n",test++);
        B1+=k1;
        ans.clear();
        int a,b;
        for(int a=1;a<c;a++)
        {
            int ab1=pow_mod(a,B1,c);
            int b=c-ab1;
            if(b<=0||b>=c)continue;
            if(pow_mod(a,k1,c)==pow_mod(b,k2,c))
             ans.push_back((T){a,b});
        }
        sort(ans.begin(),ans.end());
        if(!ans.size()) puts("-1");
        for(int i=0;i<ans.size();i++)
            printf("%d %d\n",ans[i].a,ans[i].b);
    }
    return 0;
}


感谢赵同学给我讲题。

题目链接:点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: