P2564 [SCOI2009] 生日礼物

P2564 [SCOI2009] 生日礼物

题目翻译:

给你每个珠子的位置和种类,你要求出一个最小的区间,使里面包含所有种类的珠子。

思路:

我们可以发现,若一个区间的边缘上的珠子,在该区间内已经有了,那这个珠子就没必要拿,那我们只需要找到第一个包含所有的区间,在从左往又看,看这个珠子能否删去,若能,则删去,不能就继续往右加珠子,其中维护一个最小 \(ans\) 即可

完整代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
struct A{
	int x,op;
	bool operator<(const A &q)const{return x<q.x;} 
}a[N];
map<int,int>sum;
int main(){
	int n,k;
	scanf("%d%d",&n,&k);
	for(int i=1,cnt=0;i<=k;i++){
		int t;
		scanf("%d",&t);
		while(t--){
			int x;
			scanf("%d",&x);
			a[++cnt]={x,i};
		}
	}
	sort(a+1,a+1+n);
	int ans=1e9;
	for(int l=1,r=1,kinds=0;r<=n;r++){
		if(!sum[a[r].op]){
			kinds++;
			
		}
		sum[a[r].op]++;
		while(l<=r && sum[a[l].op]>=2){
			sum[a[l].op]--;
			l++;
		}
		if(kinds==k){
			ans=min(ans,a[r].x-a[l].x);
		}
		
	}
	printf("%d",ans);
}
posted @ 2025-01-20 19:33  XichenOC  阅读(9)  评论(0)    收藏  举报