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\n", a, b); flag = true; } } if (!flag) printf("-1\n"); } int main() { //freopen("test.in", "r", stdin); int times = 1; while (scanf("%d%d%d%d", &c, &k1, &b1, &k2) != EOF) { printf("Case #%d:\n", times); work(); times++; } return 0; }