按照exCRT合并两个方程的方法做的,虽然我不会exCRT但是赛后发现推出来的式子确实是exCRT。
过了样例并且WA On Pretest 10。
总感觉是long long或二分上界的问题,但是都define int long long了,二分上界也是理论的最高界,不应该WA啊/kk
#include <cstdio>
#define int long long
int hhh[500005], pos[1000005], n, m, K;
int gcd(const int x, const int y) {return y == 0 ? x : gcd(y, x % y);}
void exgcd(const int a, const int b, int& x, int &y) {
if (!b) x = 1LL, y = 0LL;
else exgcd(b, a % b, y, x), y -= a / b * x;
}
int inv(const int a, const int mod) {
int x, y;
exgcd(a, mod, x, y);
return (x + mod) % mod;
}
bool check(const int mid) {
int ans(0LL);
for (int i(1); i <= n; ++ i) {
if (pos[hhh[i]] == 0) continue;
int a(i % n), b(pos[hhh[i]] % m);
if ((a - b) % gcd(n, m)) continue;
int x, y;
exgcd(n, m, x, y);
x = x / gcd(n, m) * (b - a);
y = y / gcd(n, m) * (b - a);
int l(n / gcd(n, m) * m);
int k(((n * x % l) + a) % l);
ans += (mid / l + (k == 0LL ? 0LL : mid % l >= k));
}
return mid - ans < K;
}
signed main() {
scanf("%lld%lld%lld", &n, &m, &K);
for (int i(1); i <= n; ++ i) scanf("%lld", hhh + i);
for (int i(1); i <= m; ++ i) {
int x;
scanf("%lld", &x);
pos[x] = i;
}
int l(1LL), r(5000000000000000000LL);
while (l < r) {
const int mid(l + r >> 1);
if (check(mid)) l = mid + 1;
else r = mid;
}
printf("%lld", l);
return 0;
}