Increasing Frequency CodeForces - 1082E
阿新 • • 發佈:2018-12-12
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; }