此题的大意是给你一个式子 a k1⋅n+b1 + b k2⋅n−k2+1 = 0 (mod C)(n = 1, 2, 3, ...), (1≤a,b<C) .要求求出这样一对整数对(a,b)使得对任意的n使此等式成立,并将(a,b)按字典序输出,如果没有满足要求的这样的整数对,就输出-1.
这道题是一道快速幂的题目但结合了同余式,所以事先得对同余式进行化简。
参考了网上的想法,当n=1时,a^(k1+b1) + b = 0 (mod C) ①
当n=2时,a^(2*k1+b1) + b^(k2+1) = 0 (mod C) ②
对①式两边同乘a^k1得:a^k1 * (a^(k1+b1) + b) = 0 (mod C) 即:a^(2*k1+b1) + a^k1 * b = 0 (mod C) ③
结合②③得 a^(2*k1+b1) + a^k1 * b = a^(2*k1+b1) + b^(k2+1) 0 (mod C) ④
化简④式得a^k1 = b^k2 ⑤
得到⑤式后,因为要将(a,b)按字典序输出,所以for循环将a从1开始循环至C,对于每一个a的值用快速幂求出
a^(k1+b1),然后由①式得到b,在用快速幂算出a^k1 和 b^k2以判断⑤式是否成立,成立输出即可,数据用long long类型。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long LL;
LL pow_mod(LL a,LL n,LL m)
{
if(n==0)
return 1;
LL x=pow_mod(a,n/2,m);
LL ans = x*x%m;
if(n%2==1)ans=ans*a%m;
return ans;
}
int main()
{
//freopen("input.txt","r",stdin);
int time=0;
LL c, k1, k2, b1;
while(scanf("%lld%lld%lld%lld",&c,&k1,&b1,&k2)!=EOF)
{
time++;
printf("Case #%d:\n",time);
bool flag=0;
for(LL i=1;i<c;i++)
{
LL left=pow_mod(i,k1,c);
LL b=c-pow_mod(i,k1+b1,c);
LL right=pow_mod(b,k2,c);
if(left==right)
{
flag=1;
printf("%lld %lld\n",i,b);
}
}
if(!flag)
printf("-1\n");
}
return 0;
}