1293: [SCOI2009]生日礼物

1293: [SCOI2009]生日礼物

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1096  Solved: 584
[ Submit][ Status]

Description

小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。 小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。

Input

第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。

Output

应包含一行,为最短彩带长度。

Sample Input

6 3
1 5
2 1 7
3 1 3 8

Sample Output

3

HINT

有多种方案可选,其中比较短的是1~5和5~8。后者长度为3最短。
【数据规模】
对于50%的数据, N≤10000;
对于80%的数据, N≤800000;
对于100%的数据,1≤N≤1000000,1≤K≤60,0≤彩珠位置<2^31。

Source

 

 题解:这个嘛,终于没有脑抽啦(phile:好评如潮 HansBug:么么哒)。。。思路也比较简单,就是直接通过那个啥的各个柱子(HansBug:啊呸,珠子 phile:你啊一看就是被Aruba多了。。。 HansBug:TT这都被你发现了)的坐标从小到大排个序,然后先从1开始找一段最短的可满足题意的子段,记录下长度,然后把这个子段第一个位置的各个珠子全部扔掉,再在结尾处往下扩充,每次都尽可能少的扩充但是要满足扩充后能包含M种珠子,然后每次记录下当前段的长度,这样子滚过去一边就可以啦,理论复杂度为O(nlogn+n)(PS:1.提醒一下,注意彩珠位置可以是0,所以在排序的数组中建议存储时+1,反正不影响结果,而且后续处理时少不少麻烦 2.这题居然3928ms我也是醉了,估计这个序列比较有序,所以快排比较逗比么么哒)

 

  1 var

 2    i,j,k,l,m,n,ll:longint;
 3    a,b,c: array[ 0.. 1000500of longint;
 4  procedure swap( var x,y:longint);
 5            var z:longint;
 6            begin
 7                z:=x;x:=y;y:=z;
 8            end;
 9  procedure sort(l,r:longint);
10            var i,j,x,y:longint;
11            begin
12                i:=l;j:=r;x:=a[(i+j)  div  2];
13                 repeat
14                       while a[i]<x  do inc(i);
15                       while a[j]>x  do dec(j);
16                       if i<=j  then
17                          begin
18                              swap(a[i],a[j]);
19                              swap(b[i],b[j]);
20                              inc(i);dec(j);
21                          end;
22                 until i>j;
23                 if i<r  then sort(i,r);
24                 if l<j  then sort(l,j);
25            end;
26  begin
27      readln(n,m);
28      fillchar(a,sizeof(a), 0);
29      fillchar(b,sizeof(b), 0);
30       for i:= 1  to m  do
31           begin
32               read(l);
33                for j:= 1  to l  do
34                    begin
35                        read(k);
36                        inc(a[ 0]);a[a[ 0]]:=k+ 1;
37                        b[a[ 0]]:=i;
38                    end;
39               readln;
40           end;
41      a[ 0]:= 0;l:= 0;
42      sort( 1,n);
43      fillchar(c,sizeof(c), 0);
44      i:= 1;
45      j:= 1;
46       while (l<m)  and (j<=n)  do
47             begin
48                 k:=j;
49                  while a[j]=a[k]  do
50                        begin
51                            inc(c[b[j]]);
52                             if c[b[j]]= 1  then inc(l);
53                            inc(j);
54                        end;
55             end;
56       if j>n  then halt;
57      ll:=a[j- 1]-a[i];
58       while j<=n  do
59             begin
60                 k:=i;
61                  while a[i]=a[k]  do
62                        begin
63                            dec(c[b[i]]);
64                             if c[b[i]]= 0  then dec(l);
65                            inc(i);
66                        end;
67                  while (l<m)  and (j<=n)  do
68                        begin
69                            k:=j;
70                             while (l<m)  and (a[j]=a[k])  do
71                                   begin
72                                       inc(c[b[j]]);
73                                        if c[b[j]]= 1  then inc(l);
74                                       inc(j);
75                                   end;
76                        end;
77                  if l<m  then break;
78                  if (a[j- 1]-a[i])<ll  then ll:=a[j- 1]-a[i];
79             end;
80      writeln(ll);
81  end.                        

转载于:https://www.cnblogs.com/HansBug/p/4192480.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值