有多种方案可选,其中比较短的是1~5和5~8。后者长度为3最短。 【数据规模】 对于50%的数据, N≤10000; 对于80%的数据, N≤800000; 对于100%的数据,1≤N≤1000000,1≤K≤60,0≤彩珠位置<2^31。
单调栈~
o(n)扫描一遍,如果总种类数=k,就更新答案,否则就退栈。
结果不能用ri-le来更新,为什么啊……
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m,x,num[61],le,ri,cnt,ans; struct node{ int x,id; }a[1000001],q[1000001]; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();} while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } bool operator < (node u,node v) { return u.id<v.id; } void in(int i) { num[a[i].x]++; if(num[a[i].x]==1) x++; q[++ri]=a[i]; } void out() { num[q[++le].x]--; if(!num[q[le].x]) x--; } int main() { n=read();m=read(); for(int i=1;i<=m;i++) { x=read(); for(int j=1;j<=x;j++) a[++cnt].id=read(),a[cnt].x=i; } sort(a+1,a+n+1);x=0;ans=999999999; for(int i=1;i<=n;i++) { in(i); while(x==m) { ans=min(ans,q[ri].id-q[le+1].id);out(); } } printf("%d",ans); return 0; }
