bzoj1293: [SCOI2009]生日礼物(stl堆)

1293: [SCOI2009]生日礼物

题目:传送门 

题解:

   据说这道题乱搞随便就水过了

   本蒟蒻想到了一个用堆的水法(还专门学了学queue):

   如果把每一种颜色的下一个位置都记录一下的话,一开始就把所有的颜色开头位置加入堆中,求一下ans

   然后将最左边的颜色删掉换成下一个位置并加入堆然后更新答案

   因为题目保证位置升序,所以如果问当前颜色的没有了下一个位置,那就退出

代码(有点丑,因为不会求堆底所以开了两个堆):

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<queue>
 7 using namespace std;
 8 typedef long long LL;
 9 
10 int n,k;
11 struct node
12 {
13     LL x;int next;
14     node(){next=-1;}
15     friend bool operator <(node n1,node n2)
16     {
17         return n1.x>n2.x;
18     }
19 }a[1100000];
20 struct node1
21 {
22     LL x;
23     friend bool operator <(node1 n1,node1 n2)
24     {
25         return n1.x<n2.x;
26     }
27 }b[1100000];
28 priority_queue<node> q;
29 priority_queue<node1> v;
30 void clean(){while(q.empty()!=true)q.pop();}
31 int t[65];
32 int main()
33 {
34     clean();int id=0;
35     scanf("%d%d",&n,&k);LL x;
36     for(int i=1;i<=k;i++)
37     {
38         scanf("%d",&t[i]);
39         for(int j=1;j<=t[i];j++)
40         {
41             scanf("%lld",&x);
42             a[++id].x=x;if(j!=t[i])a[id].next=id+1;
43             b[id].x=x;
44         }
45     }
46     int w=1;
47     for(int i=1;i<=k;i++)
48     {
49         if(i!=1)w+=t[i-1];
50         q.push(a[w]);v.push(b[w]);
51     }
52     node1 n1=v.top();
53     node n2=q.top();
54     LL ans=n1.x-n2.x;
55     while(1)
56     {
57         node no=q.top();
58         if(no.next==-1)break;
59         q.pop();q.push(a[no.next]);v.push(b[no.next]);
60         n1=v.top();n2=q.top();
61         ans=min(ans,n1.x-n2.x);
62     }
63     printf("%lld\n",ans);
64     return 0;
65 }

 

posted @ 2018-02-27 20:31  CHerish_OI  阅读(132)  评论(0编辑  收藏  举报