Title

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;
}

posted @ 2022-03-22 21:22  BeautifulWater  阅读(250)  评论(0编辑  收藏  举报