Educational Codeforces Round 55 (Rated for Div. 2) E Increasing Frequency(dp)

題目鏈接:http://codeforces.com/contest/1082/problem/E

E. Increasing Frequency

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You are given array aa of length nn. You can choose one segment [l,r][l,r] (1≤l≤r≤n1≤l≤r≤n) and integer value kk (positive, negative or even zero) and change al,al+1,…,aral,al+1,…,ar by kk each (i.e. ai:=ai+kai:=ai+k for each l≤i≤rl≤i≤r).

What is the maximum possible number of elements with value cc that can be obtained after one such operation?

Input

The first line contains two integers nn and cc (1≤n≤5⋅1051≤n≤5⋅105, 1≤c≤5⋅1051≤c≤5⋅105) — the length of array and the value cc to obtain.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤5⋅1051≤ai≤5⋅105) — array aa.

Output

Print one integer — the maximum possible number of elements with value cc which can be obtained after performing operation described above.

Examples

input

Copy

6 9
9 9 9 9 9 9

output

Copy

6

input

Copy

3 2
6 2 6

output

Copy

2

Note

In the first example we can choose any segment and k=0k=0. The array will stay same.

In the second example we can choose segment [1,3][1,3] and k=−4k=−4. The array will become [2,−2,2][2,−2,2].

 

題意:給你n(n<=1e5)個數和一個數c,你只能把一段連續區間裏的數都加上k(k由你自己定),使得整個序列含c儘可能的多。

思路:剛開始想線段樹、RMQ那邊去了,因爲顯然是從某處開始,前面的c的數量和後面的c的都已經確定,把中間這段數中出現次數最多的數都變成c。但是你要枚舉前面用了多少c,後面用了多少c已經是O(n*n),而且中間出現次數最多的數不好計算。於是我就自閉了。

看了別人的代碼瞬間醒悟。。。只需要dp一下就行了。

dp[i]表示從前面某個位置pos開始,到現在的位置i,把pos~i之間的(出現次數最多的)數變成c,前pos-1個不變的最大的含c的數量。

pre[x]=j表示對於某個數a[i]==x,它上一次出現的位置是j。即a[j]=a[i]=x。

qian[i]表示從第一個位置到當前位置i時c出現的次數。

hou[i]表示從最後一個位置到當前位置i時c出現的次數。

那麼狀態轉移方程就出來了:

dp[i]=max(qian[i-1]+1,dp[pre[a[i]]]+1);

pre[i]=i;

ans=max(ans,dp[i]+hou[i+1]);

這樣就可以保證某個位置pos開始,dp[pos+1]~dp[i]這一段出現次數最多的數都變成了c的最大的c的數量。

以上思路值得好好思考。

代碼:

#include<bits/stdc++.h>
#define ll long long
#define mp make_pair
using namespace std;
const int maxn=500000+10;
int n,k,m;
int cnt,tmp,flag,ans;
int dp[maxn];
int a[maxn],c[maxn],pre[maxn],qian[maxn],hou[maxn];
int main()
{

    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        qian[i]=qian[i-1]+(a[i]==k);
    }
    for(int i=n;i>=1;i--)
    {
        hou[i]=hou[i+1]+(a[i]==k);
    }
    for(int i=1;i<=n;i++)
    {
        dp[i]=max(qian[i-1]+1,dp[pre[a[i]]]+1);
        pre[a[i]]=i;
        ans=max(ans,dp[i]+hou[i+1]);
    }
    printf("%d\n",ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章