bzoj 1293 贪心
首先我们可以将这道题看成一个数轴,数轴其中的某些点存在一些颜色,我们要选取最短的一段,使这段存
在所有颜色,那么我们使用指针i,j表示在j-i位置中包含的颜色,那么初值是0,0,我们先i++,同时添加i位置
的颜色,直到j-i中存在所有颜色,然后j++,同时删除颜色,直到不存在所有颜色,然后更新答案,重复这过程,
因为i,j只增不减,所以是o(n)的,但是要离散化,还是nlogn的,也算是贪心吧
/************************************************************** Problem: 1293 User: BLADEVIL Language: Pascal Result: Accepted Time:3968 ms Memory:23664 kb ****************************************************************/ //By BLADEVIL var n, k :longint; a, c, size :array[0..1000010] of longint; flag :array[0..100] of longint; tot :longint; l :longint; pre, other :array[0..1000010] of longint; last :array[0..1000010] of longint; function min(a,b:longint):longint; begin if a>b then min:=b else min:=a; end; procedure swap(var a,b:longint); var c :longint; begin c:=a; a:=b; b:=c; end; procedure connect(x,y:longint); begin inc(l); pre[l]:=last[x]; last[x]:=l; other[l]:=y; end; procedure qs(low,high:longint); var i, j :longint; xx :longint; begin i:=low; j:=high; xx:=a[(i+j) div 2]; while i<j do begin while a[i]<xx do inc(i); while a[j]>xx do dec(j); if i<=j then begin swap(a[i],a[j]); swap(c[i],c[j]); inc(i); dec(j); end; end; if i<high then qs(i,high); if j>low then qs(low,j); end; procedure init; var i, j :longint; x, y :longint; begin read(n,k); for i:=1 to k do begin read(x); for j:=1 to x do begin read(y); inc(tot); a[tot]:=y; c[tot]:=i; end; end; qs(1,tot); end; procedure main; var i, j :longint; cur :longint; ans, sum :longint; q, p :longint; begin tot:=0; cur:=-1; for i:=1 to n do begin if a[i]<>cur then begin inc(tot); size[tot]:=a[i]; cur:=a[i]; connect(tot,c[i]); end else begin connect(tot,c[i]); end; end; ans:=maxlongint; i:=0; j:=0; sum:=0; fillchar(flag,sizeof(flag),0); while i<tot do begin while sum<k do begin inc(i); q:=last[i]; while q<>0 do begin p:=other[q]; if flag[p]=0 then begin flag[p]:=1; inc(sum); end else inc(flag[p]); q:=pre[q]; end; if i>tot then break; end; if i>tot then break; while sum>=k do begin inc(j); q:=last[j]; while q<>0 do begin p:=other[q]; dec(flag[p]); if flag[p]=0 then dec(sum); q:=pre[q]; end; if j>tot then break; end; ans:=min(ans,size[i]-size[j]); end; writeln(ans); end; begin init; main; end.