C. Klee in Solitary Confinement
C. Klee in Solitary Confinement
给定一个长度为n的序列,可以对一个子序列内所有的数字进行加k操作且有且最多进行一次,求如何选择l和r使得总序列总数的r最大。
假设挑一段序列L到R,假设有确定的总数为x,则答案为除去子序列L到R的其他x的个数和子序列L到R新进成为x的个数(即原来为x-k)。
设sum[i][0],sum[i][1]
分别为位置i前x的个数和x-k的个数,
则对于对区间L到R进行加k操作后的答案为sum[n][0]-(sum[R][0]-sum[L-1][0])+(sum[R][1]-sum[L-1][1])
sum[n][0]+(sum[R][1]-sum[R][0])+(sum[L-1][0]-sum[L-1][1])
(依次遍历右端点R,动态维护L-1的最大值,即可线性算出)
然后将所有的\(a_i\)进行一遍考虑
(注意若k=0,则会将本身丢进去)
#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define MAX 1000005
#define MOD 1000000007
#define PB push_back
using namespace std;
const int N = 1E6+5,M = 4E6+100;
int n,k,a[N],offset = 2e6;
int sum[N][2];
int cnt[M];
vector<int > vec[M];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
int ans = 0;
int maxn = 0;
repd(i,1,n)
{
cin>>a[i];
a[i] += offset;
cnt[a[i]]++;
maxn = max(maxn,cnt[a[i]]);
vec[ a[i] ].PB(a[i]) , vec[ a[i]+k ].PB(a[i]);
}
if(k==0)
{
cout<<maxn<<endl;
return 0;
}
repd(i,0,4e6)
{
if(vec[i].size()==0) continue;
sum[0][0] = sum[1][0] = 0;
rep(j,0,vec[i].size())
{
sum[j+1][0] = sum[j][0] + (vec[i][j] == i);
sum[j+1][1] = sum[j][1] + (vec[i][j] != i);
}
int temp = 0;
repd(j,1,vec[i].size())
{
temp = max(temp,sum[j-1][0]-sum[j-1][1]);
ans = max(ans,sum[vec[i].size()][0]+(sum[j][1]-sum[j][0])+temp);
}
}
cout<<ans;
return 0;
}