题目简意:给定长度为n的数列a,求数列中出现1~m的最短区间。
对于 100% 的数据,有 1≤n≤106,1≤ai≤m≤2×103。
思路:枚举左端点并求得每个左端点的最小区间,然后去最小值。
代码(c++):
#include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define of(i,a,b) for(int i=a;i>=b;--i)
#define ll long long
const int mod=1e6+7;
const int Mod=1e9+7;
const int inf=0x3f3f3f3f;
const int INF=0x7fffffff;
const int Maxn=1e6+10;
int data[Maxn],tot[Maxn];
int w;
void del(int x) {w-=(!(--tot[data[x]]));}
void add(int x) {w+=(!(tot[data[x]]++));}
int main()
{
int n,m;scanf("%d%d",&n,&m);
fo(i,1,n) scanf("%d",&data[i]);
int ans_le=0,ans_ri=inf;
for(int le=1,ri=0;le<=n;del(le++))
{
while(w!=m&&ri<n) add(++ri);
if(w==m&&(ri-le<ans_ri-ans_le)) {ans_le=le; ans_ri=ri;}
else break;
}
printf("%d %d\n",ans_le,ans_ri);
return 0;
}
/*
in1:
10 5
3 4 2 5 4 3 2 1 5 5
out1:
4 8
*/