卧薪尝胆,厚积薄发。
SCOI2009 生日礼物
Date: Mon Sep 24 14:43:26 CST 2018 In Category: NoCategory

Description:

一条彩带有些位置上有不同颜色的珠子,选一段最短的区间使得包含所有种类的珠子。
$1\leqslant n \leqslant 10^6$

Solution:

裸双指针。

Code:


#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<vector>
#include<cstring>
using namespace std;
int n,m;
#define MAXN 1000010
#define MAXM 61
struct ball
{
int col,pos;
}s[MAXM * MAXN];
int tot = 0;
bool cmp_p(ball a,ball b){return a.pos < b.pos;}
int cnt[MAXM];
int main()
{
scanf("%d%d",&n,&m);
int w;
for(int i = 1;i <= m;++i)
{
scanf("%d",&w);
for(int k = 1;k <= w;++k)
{
++tot;s[tot].col = i;
scanf("%d",&s[tot].pos);
}
}
sort(s + 1,s + 1 + tot,cmp_p);
int l = 1,r = 0;
int sum = 0;
int ans = 0x3f3f3f3f;
while(r < tot)
{
++r;++cnt[s[r].col];if(cnt[s[r].col] == 1)++sum;
while(cnt[s[l].col] > 1){--cnt[s[l].col];++l;}
if(sum == m)ans = min(ans,s[r].pos - s[l].pos);
}
cout << ans << endl;
return 0;
}
Copyright © 2020 wjh15101051
ღゝ◡╹)ノ♡