我用的二分+单调队列变式。。不会用堆,还写得丑,,跑到3000+ms。。
【代码】
#include <cstdio>
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <stack>
#define N 1000005
#define M 200005
#define INF 0x7fffffff
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pa;
int read()
{
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
int n,m,cnt,ans;
int num[65],Q[N];
class node{
public:
int pos,t;
}e[N];
bool cmp(node a,node b){
return a.pos<b.pos;
}
bool Judge(int mid)
{
for(int i=1;i<=n;i++) num[i]=0;
int head=1,tail=0,sum=0;
for(int i=1;i<=n;i++)
{
Q[++tail]=i;
num[e[i].t]++;
if(num[e[i].t]==1) sum++;
while(head<=tail&&e[Q[tail]].pos>e[Q[head]].pos+mid)
{
num[e[Q[head]].t]--;
if(!num[e[Q[head]].t]) sum--;
head++;
}
if(sum==m) return true;
}
return false;
}
void B_Search()
{
int l=0,r=e[n].pos-e[1].pos;
while(l<=r)
{
int mid=l+r>>1;
if(Judge(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=m;i++)
{
int x=read();
while(x--)
{
e[++cnt].pos=read();
e[cnt].t=i;
}
}
sort(e+1,e+1+n,cmp);
B_Search();
return 0;
}