http://codeforces.com/contest/1082/problem/E
对每种颜色分开考虑 对第i种颜色 在线段树对应点上更新为1 对第c种颜色 在线段树对应点上更新为-1 求一下最大子段和 就是把第i种颜色变为第c种的增量 取个最大值即可
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
const int maxn=5e5+10;
struct node
{
int sum,left,right,all;
};
vector <int> pre[maxn];
node tree[4*maxn];
int n,c;
void pushup(int cur)
{
tree[cur].sum=tree[2*cur].sum+tree[2*cur+1].sum;
tree[cur].left=max(tree[2*cur].left,tree[2*cur].sum+tree[2*cur+1].left);
tree[cur].right=max(tree[2*cur+1].right,tree[2*cur+1].sum+tree[2*cur].right);
tree[cur].all=max(max(tree[2*cur].all,tree[2*cur+1].all),tree[2*cur].right+tree[2*cur+1].left);
}
void update(int tar,int val,int l,int r,int cur)
{
int m;
if(l==r){
tree[cur].sum=tree[cur].left=tree[cur].right=tree[cur].all=val;
return;
}
m=(l+r)/2;
if(tar<=m) update(tar,val,l,m,2*cur);
else update(tar,val,m+1,r,2*cur+1);
pushup(cur);
}
int main()
{
int i,j,tmp,sum,ans,res;
scanf("%d%d",&n,&c);
sum=0;
for(i=1;i<=n;i++){
scanf("%d",&tmp);
if(tmp==c){
sum++;
update(i,-1,1,n,1);
}
else pre[tmp].pb(i);
}
ans=sum;
for(i=1;i<=500000;i++){
if(i==c) continue;
for(j=0;j<pre[i].size();j++){
update(pre[i][j],1,1,n,1);
}
ans=max(ans,sum+tree[1].all);
for(j=0;j<pre[i].size();j++){
update(pre[i][j],0,1,n,1);
}
}
printf("%d\n",ans);
return 0;
}