P9978 [USACO23DEC] Cycle Correspondence S - Solution
赛时差点没切。
这个题目描述很屎,要手模一下我才发现两个结论:
举例来说,样例三:
6 4
1 2 3 4
4 3 2 5
我们令
第一类的贡献非常好算,因为值域是
第二类贡献,考虑令
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long int ll;
using pll = pair<ll, ll>;
const int maxn = 5e5 + 10;
const ll mod = 998244353LL;
const ll inf = 1145141919810LL;
int n, k; ll a[maxn], b[maxn], cnt[maxn], sum[maxn]; int d[maxn]; pll c[maxn];
int main() {
scanf("%d%d", &n, &k); ll ans = 0;
for (int i = 1; i <= k; i++) scanf("%lld", &a[i]), ++cnt[a[i]], d[a[i]] = i;
for (int i = 1; i <= k; i++) scanf("%lld", &b[i]), ++cnt[b[i]];
for (int i = 1; i <= k; i++) {
int u = d[b[i]];
if (!u) continue;
if (u >= i) ++sum[u - i];
else ++sum[k - i + u];
}
for (int i = 0; i <= k; i++) ans = max(ans, sum[i]);
reverse(a + 1, a + k + 1); memset(d, 0, sizeof(d)); memset(sum, 0, sizeof(sum));
for (int i = 1; i <= k; i++) d[a[i]] = i;
for (int i = 1; i <= k; i++) {
int u = d[b[i]];
if (!u) continue;
if (u >= i) ++sum[u - i];
else ++sum[k - i + u];
}
for (int i = 0; i <= k; i++) ans = max(ans, sum[i]);
for (int i = 1; i <= n; i++) ans += !cnt[i];
printf("%lld\n", ans);
return 0;
}