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.
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
分析:我们先将公式变一下形为: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;
}
感谢赵同学给我讲题。
题目链接:点击打开链接