codeforces+E. Increasing Frequency+技巧
阿新 • • 發佈:2019-01-01
題目連結:http://codeforces.com/contest/1082/problem/E
題目大意:給你一個長度為序列,和一個c,你可以對一個區間[l,r] (l<=r)內的所有元素,進行加或者減一個k,只能操作一次。問你這樣得到的序列中c元素最多為多少?(1≤n≤5⋅10^5 )
思路:如果列舉每個區間。那麼複雜度為O(n ^2)。超時。
因為翻轉的區間裡內的相同數字的個數大於c的個數。這樣才能使得c的個數增多。但是我們可以從0開始,如果0-x區間內。c的個數>=相同數字的最大個數那麼這個區間就肯定不會翻轉。這個時候可以把所有的個數清0,重新統計。但是可以使得次時的個數a[i]=c的個數cut,那麼就可以用a[i]-cut統計翻轉此區間能額外的個數。
所以只要把序列掃一遍輸出cut+max(a[i]-cut)就行了。
#include<bits/stdc++.h> using namespace std; const int MAX= 500005; int a[MAX]; int main() { fill(a, a+MAX, 0); int n, k, cut=0, m=0, x; cin>>n>>k; for(int i=0;i<n;i++) { scanf("%d",&x); if(x==k)/*統計k的個數*/ cut++; else { if(a[x]<cut)/*翻轉此區間不能得到額外的k的個數*/ a[x]=cut;/* 置'0' */ a[x]++; m=max(m, a[x]-cut);/*統計能額外得到的k的最大個數/ } } cout<<m+cut<<endl; return 0; }