序列游戏

Problem

有一个长度为 \(n\) 的序列 \(a\)。你可以去掉 \(k\) 种权值的数字,使新的序列存在最长的权值相同的区间。

求这个最长区间的长度。

\(1 \le k \le n \le 10^5,1 \le a_i \le 10^9\)

Input

第一行包括两个整数 \(n\)\(k\),分别表示序列的长度和去掉的权值种类。

接下来 \(n\) 行,每行包括一个整数 \(a_i\),表示序列中的第 \(i\) 个元素。

Output

输出包括一个整数,表示去掉k种元素后,最长的权值相同的区间的长度。

Sample

Input 1

9 1
2
7
3
7
7
3
7
5
7

Output 1

4

Solution

双指针题。

对于右指针 \(r\),我们需要找到在它前面离它最远的符合条件 \(l\)。可以证明,离 \(r\) 越远,就越难符合条件。

\(map\) 存下每种数出现的次数,再记录下数的种类数。如果超过限制,移动左指针 \(l\) 即可。

代码:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>

using namespace std;

const int kmax = 1e5 + 3;

int n, k;
int a[kmax];
map<int, int> mp;
int c, res;

int main() {
  cin >> n >> k;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1, j = 1; j <= n; j++) {
    c += ++mp[a[j]] == 1; // 右指针移动
    for (; c > k + 1; i++) { // 超过,移动左指针
      c -= --mp[a[i]] == 0;
    }
    res = max(res, mp[a[j]]); // 记录答案
  }
  cout << res;
  return 0;
}
posted @ 2023-05-08 11:03  ereoth  阅读(38)  评论(0)    收藏  举报