NOIP 2016 蚯蚓

https://www.luogu.org/problem/P2827

NOIP 2016 D2T2

比较朴素的想法是开一个大根堆,每次取出堆顶元素,切开放回去;

问题在于怎么维护每次增长的q长度;

 根据相对论 可以想到,拿出的蚯蚓不增长,其它蚯蚓增长,等价于拿出的蚯蚓变短;

那么我们只需要维护蚯蚓增长的长度SUM,每次取出蚯蚓时加上SUM+=q,切开后每段减去SUM,最后统计时再加上总的SUM就好了;

但这样复杂度还是太高;

考虑到每次拿出最长的,后切开的两段肯定比先切开的两段短;

所以本身就有单调性,不用堆维护也可以;

参考网上的题解,开三个数组,分别储存切前的A1,切的第一段A2,切的第二段A3,每次从三个数组中选出最长的,切成两段,放到A2,A3中就好啦哇;


 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 const int M=7000002;
 8 int h0,h1,h2,n,m,res,cnt,num;
 9 int t0,t1,t2,q,u,v,top,a1,a2,t,sum;
10 int cut1[M],cut2[M],cut0[M];
11 double p;
12 int ans[M];
13 bool cmp(int x,int y){
14     return x>y;
15 }
16 int main(){
17     scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
18     p=(double)u/v;
19     for(int i=1;i<=n;i++)
20        scanf("%d",&cut0[i]);
21     sort(cut0+1,cut0+1+n,cmp);
22     t0=n;h1=h2=h0=1;t1=t2=0;
23     for(int i=1;i<=m;i++){
24         if(h0>t0){if(cut1[h1]>cut2[h2])top=cut1[h1++];else top=cut2[h2++];}
25         else if(cut0[h0]>=cut1[h1]&&cut0[h0]>=cut2[h2])top=cut0[h0],++h0;
26         else if(cut1[h1]>=cut2[h2]&&cut0[h0]<=cut1[h1])top=cut1[h1],++h1;
27         else top=cut2[h2],++h2;
28         top+=sum;
29         a1=floor(p*(double)top);
30         a2=top-a1;
31         sum+=q;        
32         a1-=sum;
33         a2-=sum;
34         cut1[++t1]=a1;
35         cut2[++t2]=a2;
36         if(i%t==0) printf("%d ",top);
37     }
38     
39     printf(" \n");
40     for(int i=h0;i<=t0;i++) ans[++num]=cut0[i];
41     for(int i=h1;i<=t1;i++) ans[++num]=cut1[i];
42     for(int i=h2;i<=t2;i++) ans[++num]=cut2[i];
43     sort(ans+1,ans+1+num,cmp);
44     for(int i=1;i<=num;i++){
45         if(i%t==0) printf("%d ",ans[i]+sum);
46     }
47     return 0;
48 }
蚯蚓

 

posted @ 2019-10-05 11:42  _loverr  阅读(137)  评论(0编辑  收藏  举报
Live2D