[CF1082E] Increasing Frequency - dp
Description
给你一个长度为 (n) 的数列 (a) ,你可以任意选择一个区间 ([l,r]), 并给区间每个数加上一个整数 (k), 求这样一次操作后数列中最多有多少个数等于 (c).
Solution
转化为挑一个区间,最大化众数数目减去 (c) 数目
暴力的方法是,对每个元素(假设它是众数),拿着数目差去做一次最大子段和
如果处理出一个前缀和,我们在扫到每个数的时候,需要的是它之前有过的最小数目差
因此对于每个数都维护一个最小数目差,每次扫到一个元素时用当前数目差和以前的最小数目差相减去更新答案,然后用当前值去更新最小数目差即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e6 + 5;
int a[N], f[N], c, n, ans, cnt[N];
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> c;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
{
int delta = cnt[a[i]] - cnt[c];
f[a[i]] = min(f[a[i]], delta);
cnt[a[i]]++;
delta = cnt[a[i]] - cnt[c];
ans = max(ans, delta - f[a[i]]);
}
cout << ans + cnt[c] << endl;
}