(悬赏2关注) 双指针45分求助
  • 板块P1638 逛画展
  • 楼主dtrthg
  • 当前回复2
  • 已保存回复2
  • 发布时间2023/6/18 00:04
  • 上次更新2023/10/23 12:53:24
查看原帖
(悬赏2关注) 双指针45分求助
379113
dtrthg楼主2023/6/18 00:04

题目简意:给定长度为n的数列a,求数列中出现1~m的最短区间。

对于 100%100\% 的数据,有 1≤n≤1061\leq n\le10^6,1≤ai≤m≤2×1031 \leq a_i \leq m\le2\times10^3。

思路:枚举左端点并求得每个左端点的最小区间,然后去最小值。

代码(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
*/

2023/6/18 00:04
加载中...