1. 程式人生 > >codeforces+E. Increasing Frequency+技巧

codeforces+E. Increasing Frequency+技巧

題目連結: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;
}