HDU - 5478 Can you find it
传送门HDU - 5478
题意
给你
C
C
,,
b1
b
1
,
k2
k
2
,(
C
C
为质数)。
让你求公式
所有使等式成立的 (a,b)(1≤a,b<C) ( a , b ) ( 1 ≤ a , b < C ) ,没有输出-1。
题解
第一眼看见这个题,因为C是质数,第一反应是欧拉降幂。但是欧拉降幂好像没啥卵用orz。
贴个欧拉降幂公式。
AB(modC)=AB(modϕ(C))+ϕ(C)(modC)
A
B
(
mod
C
)
=
A
B
(
mod
ϕ
(
C
)
)
+
ϕ
(
C
)
(
mod
C
)
两个未知量,那么就要两个等式就能求出来 a a 和。那么我们就直接列出 n=1 n = 1 和 n=2 n = 2 的式子。
ak1+b1+b=0(modC)(1)
(1)
a
k
1
+
b
1
+
b
=
0
(
mod
C
)
a2×k1+b1+bk2+1=0(modC)(2)
(2)
a
2
×
k
1
+
b
1
+
b
k
2
+
1
=
0
(
mod
C
)
通过 (1) ( 1 ) 和 a a 和的范围,我们可以算得
b=(c−ak1+b1)(3)
(3)
b
=
(
c
−
a
k
1
+
b
1
)
然后我们把 (1)(2) ( 1 ) ( 2 ) 移项, (2) ( 2 ) 除以 (1) ( 1 )
a2×k1+b1ak1+b1=−bk2+1−b
a
2
×
k
1
+
b
1
a
k
1
+
b
1
=
−
b
k
2
+
1
−
b
上下约分得
ak1=bk2(4)
(4)
a
k
1
=
b
k
2
这样算法就明了了,我们可以枚举 a a ,然后通过求出 b b 。
再用快速幂验证是否成立,如果成立就输出。
ac代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <iomanip>
//#include <unordered_map>
#pragma comment(linker, "/STACK:102400000,102400000")
#define fir first
#define sec second
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define clr(x) memset(x,0,sizeof(x))
#define cld(x) memset(x,-1,sizeof(x))
#define clx(x) memset(x,63,sizeof(x))
#define cln(x) memset(x,-64,sizeof(x))
#define rush() int T;scanf("%d",&T);while(T--)
#define pi 3.1415926
#define VM 100047
#define EM 400047
#define rd(x) scanf("%d",&x);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>pii;
typedef pair<ll,ll>pll;
const int inf = 0x3f3f3f3f;
const ll llf = 0x3f3f3f3f3f3f3f3f;
const int maxn = (int) 1e6 + 7;
const double eps = 1e-10;
const ll mod1 = (int) 1e9 + 7;
const ll mod2 = 998244353;
const ll has = 99959;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
ll pow(ll x, ll n, ll mod) {
ll res = 1;
while (n > 0) {
if (n % 2 == 1) {
res = res * x;
res = res % mod;
}
x = x * x;
x = x % mod;
n >>= 1;
}
return res;
}
int main(){
std::ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
ll c,k1,b1,k2;
int NUM = 0;
while(cin >> c >> k1 >> b1 >> k2){
bool flag = false;
cout << "Case #" << ++NUM << ":" << endl;
for (int i = 1; i < c; i++) {
ll a = i;
ll l = pow(a,k1 + b1,c);
ll b = (c - l);
if(pow(a,k1,c) == pow(b,k2,c)){
flag = true;
cout << a << " " << b << endl;
}
}
if(!flag){
cout << -1 << endl;
}
}
return 0;
}