您的位置:首页 > 其它

bzoj 1293: [SCOI2009]生日礼物 暴力

2016-12-23 20:49 387 查看

题意

给出n个珠子,每个珠子有一个颜色和下标,求一段最短的线段,使得线段内包含了所有颜色。

n<=1000000

分析

把所有珠子按照下标排序,预处理一个next[i]表示第i个珠子的下一个与它颜色相同的珠子的下标。

双指针维护顺便统计即可。

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N 1000005
#define M 65
using namespace std;

int n,m,tot,next
,w[M],vis[M];
struct data{int pos,color;}a
;

bool cmp(data a,data b)
{
return a.pos<b.pos;
}

int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
int s;
scanf("%d",&s);
for (int j=1;j<=s;j++)
{
int x;
scanf("%d",&x);
a[++tot].pos=x;a[tot].color=i;
}
}
sort(a+1,a+n+1,cmp);
for (int i=n;i>=1;i--)
{
next[i]=w[a[i].color];
w[a[i].color]=i;
}
int l=1,r=0,now=0,ans=0;
while (now<m)
{
r++;
if (!vis[a[r].color])
{
vis[a[r].color]=1;
now++;
}
}
ans=a[r].pos-a[l].pos;
while (r<=n)
{
if (!next[l]) break;
if (r<next[l]) r=next[l];
l++;
ans=min(ans,a[r].pos-a[l].pos);
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: