求助刚刚CF的D题
  • 板块灌水区
  • 楼主Stinger
  • 当前回复23
  • 已保存回复23
  • 发布时间2021/3/13 21:18
  • 上次更新2023/11/5 02:06:18
查看原帖
求助刚刚CF的D题
361308
Stinger楼主2021/3/13 21:18

按照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;
}
2021/3/13 21:18
加载中...