HDU 5478 Can you find it (2015年上海赛区网络赛K题)

时间:2022-08-01 18:54:06

1.题目描述:点击打开链接

2.解题思路:本题利用枚举法+随机数解决。通过分析可以发现,一个a只对应一个b,因此不妨枚举a,在n=1时候求出相应的b,接下来只需要在[1,C)范围内用随机数检测等式是否恒成立即可。通过尝试发现,用随机数测试500次即可。

3.代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define me(s) memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <ll,ll> P;


const int N = 200000 + 10;

int C;
ll k1, b1, k2;
vector<P>ans;

ll pow_mod(ll a, ll n, int M)
{
ll res = 1;
while (n>0)
{
if (n & 1)res = res*a%M;
a = a*a%M;
n >>= 1;
}
return res;
}

bool check(ll a, ll b)
{
for (int j = 0; j < 500;j++)
{
int i = rand() % C + 1;
ll r1 = (k1*i + b1) % (C - 1);
ll r2 = (k2*i - k2 + 1) % (C - 1);
ll t1 = pow_mod(a, r1, C);
ll t2 = pow_mod(b, r2, C);
if ((t1 + t2) % C)return false;
}
return true;
}
int main()
{
int rnd = 0;
srand(time(NULL));
while (~scanf("%d%d%d%d", &C, &k1, &b1, &k2))
{
printf("Case #%d:\n", ++rnd);
ans.clear();
for (int a = 1; a<C; a++)
{
ll tmp = pow_mod(a, k1 + b1, C);
ll b = C - tmp;
if (check(a, b))ans.push_back(P(a, b));
}
if (ans.empty())puts("-1");
else
{
sort(ans.begin(), ans.end());
int len = ans.size();
for (int i = 0; i<len; i++)
printf("%lld %lld\n", ans[i].first, ans[i].second);
}
}
}