1. 程式人生 > >CF616D Longest k-Good Segment

CF616D Longest k-Good Segment

格式 algo number == ood esp nts parameter space

題目描述

給定一個包含\(n\)個整數的序列\(a\)\(0\le a_i \le 10^6\),詢問不重復數字個數\(\le k\)的最長區間的左右端點。如果有多解輸出任意一組。

輸入輸出格式

輸入格式:

The first line contains two integers \(n,k\) ( \(1 \leq k \leq n \leq 5·10^{5}\)) — the number of elements in \(a\) and the parameter \(k\) .

The second line contains nn integers \(a_{i}\)? \(( 0<=a_{i}<=10^{6}\)

) — the elements of the array \(a\) .

輸出格式:

Print two integers \(l,r\) (\(1<=l<=r<=n\)) — the index of the left and the index of the right ends of some k-good longest segment. If there are several longest segments you can print any of them. The elements in aa are numbered from \(1\) to \(n\)

from left to right.

輸入輸出樣例

輸入樣例#1:

5 5
1 2 3 4 5

輸出樣例#1:

1 5

輸入樣例#2:

9 3
6 5 1 2 3 2 1 4 5

輸出樣例#2:

3 7

輸入樣例#3:

3 1
1 2 3

輸出樣例#3:

1 1

思路:題意為在長度為\(n\)的串中找出有k個不同數字的最長連續子串,輸出子串開始以及結束的位置,然而數據有點水,我們直接用\(STL\)中的\(map\)記錄一下即可。

代碼:

#include<cstdio>
#include<algorithm>
#include<map>
#define maxn 1000007
using namespace std;
map <int,int> mp;
int a[maxn],l,len,cyh,zrj;
void del(int x)
{
    mp[x]--;
    if(mp[x]==0) mp.erase(x);
}
int main() {
  int n,k;
  scanf("%d%d",&n,&k);
  for(int i=0;i<n;++i) scanf("%d",&a[i]);
  for(int i=0;i<n;++i) {
    mp[a[i]]++;
    if(mp.size()>k) {
      for(;l<n&&mp.size()>k;++l)
        del(a[l]);
    }
    int ll=i-l+1;
    if(ll>len) {
      len=ll;
      cyh=l;
      zrj=i;
    }
  }
  printf("%d %d\n",cyh+1,zrj+1);
  return 0;
}

CF616D Longest k-Good Segment