題目傳送門
(這又是一位dalao告訴我的水題)
這題明顯是一道線掃題,只要排序一下,在全部存在的情況下找出最小的答案就行了。
直接上代碼:
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,a,n) for (int i=a;i>=n;i--)
#define Clear(a,x) memset(a,x,sizeof(a))
#define ll long long
#define INF 2000000000
#define eps 1e-8
using namespace std;
ll read(){
ll x=0,f=1;
char ch=getchar();
while (ch<'0'||ch>'9') f=ch=='-'?-1:f,ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int maxn=1000005,maxk=70;
struct node{
int x,id;
}a[maxn];
int n,k,num,now,ans,len;
int sum[maxk];
bool cmp(node a,node b){
return a.x<b.x;
}
int main(){
n=read(),k=read();
rep(i,1,k){
int Long=read();
rep(j,1,Long){
a[++len].x=read();
a[len].id=i;
}
}
sort(a+1,a+n+1,cmp);
num=k;
now=1;
ans=INF;
rep(i,1,n){
if (sum[a[i].id]==0) num--;
sum[a[i].id]++;
while (num+(sum[a[now].id]-1!=0?0:1)==0&&now<i){
sum[a[now].id]--;
now++;
}
if (num==0) ans=min(ans,a[i].x-a[now].x);
}
printf("%d\n",ans);
return 0;
}