【堆】bzoj1293 [SCOI2009]生日礼物

考虑poj3320尺取法的做法,与此题基本一样,但是此题的 位置 的范围到2^31 尺取法不可。

将每种珠子所在的位置排序。

每种珠子要维护一个指针,指到已经用到这个种类的哪个珠子。

所以尺取法用堆优化,每次从堆中取出最小的,相当于尺取法的头指针向后移动。

然后从每种珠子里向后取出一个位置(指针++)(已经排过序,是单调递增的),加进堆。

再从每种其他的珠子里 把 在 新加入的珠子位置之前的 位置全都加进堆。

更新答案。

直到某种类珠子已经全用完。

由于每个位置可能有很多珠子,插入堆时要用一个二元组。

 1 #include<cstdio>
 2 #include<vector>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 struct Point
 7 {
 8     int x,y;
 9     Point(const int &a,const int &b)
10       {
11           x=a;
12           y=b;
13       }
14     Point(){}
15 };
16 bool operator < (const Point &a,const Point &b){return a.x!=b.x ? a.x<b.x : a.y<b.y;}
17 bool operator > (const Point &a,const Point &b){return a.x!=b.x ? a.x>b.x : a.y>b.y;}
18 priority_queue<Point,vector<Point>,greater<Point> >Heap;
19 vector<int>a[61];
20 vector<int>::iterator p[61];
21 int n,m,k,t,maxv,time[61],ans=2147483647;
22 Point topv;
23 int main()
24 {
25     scanf("%d%d",&n,&m);
26     for(int i=1;i<=m;i++)
27       {
28           scanf("%d",&k);
29           for(int j=1;j<=k;j++)
30             {
31             scanf("%d",&t);
32             a[i].push_back(t);
33           }
34           sort(a[i].begin(),a[i].end());
35           p[i]=a[i].begin();
36       }
37     for(int i=1;i<=m;i++)
38       {
39         maxv=max(maxv,*a[i].begin());
40         Heap.push( Point( *a[i].begin() , i ) );
41         p[i]++;
42         time[i]++;
43       }
44     for(int i=1;i<=m;i++)
45       for(;p[i]!=a[i].end()&&((*p[i])<=maxv);p[i]++)
46           {
47             time[i]++;
48             Heap.push( Point( *p[i] , i ) );
49           }
50     while(1)
51       {
52           topv=Heap.top();
53           int headv=topv.y;
54           ans=min(ans,maxv-topv.x);
55         Heap.pop();
56         time[headv]--;
57           if(!time[headv])
58             {
59                 if(p[headv]==a[headv].end())
60               break;
61                 Heap.push( Point( *p[headv] , headv ) );
62                 maxv=*p[headv];
63                 time[headv]++;
64                 for(int i=1;i<=m;i++)
65               for(;p[i]!=a[i].end()&&((*p[i])<=maxv);p[i]++)
66                   {
67                     time[i]++;
68                     Heap.push( Point( *p[i] , i ) );
69                   }
70             }
71       }
72     printf("%d\n",ans);
73     return 0;
74 }
时间: 2024-10-12 19:37:45

【堆】bzoj1293 [SCOI2009]生日礼物的相关文章

bzoj1293[SCOI2009]生日礼物 尺取法

1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2838  Solved: 1547[Submit][Status][Discuss] Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上. 小布生日快到了,于是小西打算剪一段彩带送给小

BZOJ1293: [SCOI2009]生日礼物

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1293 记录下每个点的颜色和上一个这一个颜色点的坐标,离散化之后枚举终点向前扫一遍.. #include<cstring> #include<iostream> #include<cstdio> #include<queue> #include<cmath> #include<algorithm> #define rep(i,l,r

1293: [SCOI2009]生日礼物

1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1096  Solved: 584[Submit][Status] Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上. 小布生日快到了,于是小西打算剪一段彩带送给小布.为了让礼物彩带足

BZOJ 1293: [SCOI2009]生日礼物 贪心

1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2513  Solved: 1370[Submit][Status][Discuss] Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上. 小布生日快到了,于是小西打算剪一段彩带送给小

BZOJ 1293 SCOI2009 生日礼物 堆

题目大意:给定一个数轴上n个点,每个点有一种颜色,一共k种颜色,求一个最短的区间,包含所有k种颜色 卡了一段时间0.0 一开始想二分答案啥的 后来发现数据范围太大写不了0.0 后来去找题解才发现尼玛真巧妙 维护一个堆 将每种颜色的第一个珠子加入堆 然后不断把最左侧的珠子取出,加入该种颜色的下一个 同时更新ans 果然这么大数据范围还是要用堆这种常数小的数据结构啊0.0 我手写了堆却开了STL的queue 0.0 不要说我有病我只是不习惯STL的堆罢了 #include<queue> #incl

BZOJ1293:[SCOI2009]生日礼物——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=1293 https://www.luogu.org/problemnew/show/P2564#sub 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上. 小布生日快到了,于是小西打算剪一段彩带送给小布.为了让礼物彩带足够漂亮,小西希望这一段彩带中

[SCOI2009]生日礼物

传送门 当然可以用队列来搞啦. 1 # include <iostream> 2 # include <cstdio> 3 # include <cstring> 4 # include <string> 5 # include <cmath> 6 # include <vector> 7 # include <map> 8 # include <queue> 9 # include <cstdlib&g

P2564 [SCOI2009]生日礼物?

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

bzoj 1293: [SCOI2009]生日礼物

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1559  Solved: 848[Submit][Status][Discuss] Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上. 小布生日快到了,于是小西打算剪一段彩带送给小布.为了让礼物彩带足够漂亮,小西希望这一段彩