GDCPC2023 J 题解
EuphoricStar · · 题解
当时在 GDCPC 现场是这题首杀。20min 就会了,但是 2h 才有电脑写(
观察到至多
当
当
当
-
\left\lfloor\frac{x}{a}\right\rfloor = \left\lfloor\frac{y}{b}\right\rfloor -
x \bmod a = y \bmod b
后者等价于
整除分块套个 map 找到所有
注意构造完解后要判断是否满足
时间复杂度
// Problem: J. X Equals Y
// Contest: Codeforces - The 2023 Guangdong Provincial Collegiate Programming Contest
// URL: https://codeforces.com/gym/104369/problem/J
// Memory Limit: 1024 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mkp make_pair
#define mems(a, x) memset((a), (x), sizeof(a))
using namespace std;
typedef long long ll;
typedef double db;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<ll, ll> pii;
ll X, Y, A, B;
inline ll mysqrt(ll x) {
for (ll i = max((ll)sqrt(x) - 2, 0LL);; ++i) {
if (i * i > x) {
return i - 1;
}
}
}
void solve() {
scanf("%lld%lld%lld%lld", &X, &Y, &A, &B);
if (X == Y) {
puts("YES\n2 2");
return;
}
ll sx = mysqrt(X), sy = mysqrt(Y);
map<ll, pii> M;
for (ll i = 2, j; i <= X && i <= A; i = j + 1) {
j = X / (X / i);
M[X / i] = mkp(i, min(j, A));
}
for (ll i = 2, j; i <= Y && i <= B; i = j + 1) {
j = Y / (Y / i);
if (M.find(Y / i) == M.end()) {
continue;
}
ll t = Y / i;
ll l1 = M[t].fst, r1 = M[t].scd, l2 = i, r2 = min(j, B);
if ((Y - X) % t) {
continue;
}
ll d = (Y - X) / t;
if (l2 - r1 <= d && d <= r2 - l1) {
ll a = l1;
ll b = a + d;
if (b < l2) {
ll p = l2 - b;
a += p;
b += p;
}
if (a > sx && b > sy) {
printf("YES\n%lld %lld\n", a, b);
return;
}
}
}
map< vector<ll>, ll > mp;
for (ll a = 2; a <= A && a <= sx; ++a) {
vector<ll> vc;
ll x = X;
while (x) {
vc.pb(x % a);
x /= a;
}
reverse(vc.begin(), vc.end());
mp[vc] = a;
}
for (ll a = 2; a <= B && a <= sy; ++a) {
vector<ll> vc;
ll x = Y;
while (x) {
vc.pb(x % a);
x /= a;
}
reverse(vc.begin(), vc.end());
if (mp.find(vc) != mp.end()) {
printf("YES\n%lld %lld\n", mp[vc], a);
return;
}
}
puts("NO");
}
int main() {
int T = 1;
scanf("%d", &T);
while (T--) {
solve();
}
return 0;
}