【NOIP2016提高组day2】蚯蚓

那么我们开三个不上升队列, 
第一个记录原来的蚯蚓, 
第二个记录乘以p的蚯蚓 
第三个记录乘以(1-p)的蚯蚓, 
在记录每条就要入队列的时间,就可以求出增加的长度 
每次比较三个队列的队首,取最大的值x的切。 
将xp加入第二个队列的队尾 
将x(1-p)加入第三个队列的队尾 
(第二个第三个队列保证单调,上面证明了)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 int q[4][7100010][2],ans[7100010];
 8 int n,m,Q,u,v,t,a[100010],head[5],tail[5],out;
 9 bool cmp(int a,int b)
10 {
11     return a>b;
12 }
13 int main()
14 {
15     scanf("%d%d%d%d%d%d",&n,&m,&Q,&u,&v,&t);
16     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
17     sort(a+1,a+n+1,cmp);
18     for (int i=1;i<=n;i++) q[1][i][0]=a[i];
19     head[1]=1;tail[1]=n;
20     head[2]=1;tail[2]=0;
21     head[3]=1;tail[3]=0;
22     for (int i=1;i<=m;i++)
23     {
24         long long Max=0,maxj=0;
25         for (int j=1;j<=3;j++)
26             if (head[j]<=tail[j]&&q[j][head[j]][0]+(i-1-q[j][head[j]][1])*Q>Max) Max=q[j][head[j]][0]+(i-1-q[j][head[j]][1])*Q,maxj=j;
27         head[maxj]++;
28         if (i%t==0) ans[++out]=Max;
29         q[2][++tail[2]][0]=Max*u/v;q[2][tail[2]][1]=i;
30         q[3][++tail[3]][0]=Max-Max*u/v;q[3][tail[3]][1]=i;
31     }
32     for (int i=1;i<=out;i++)
33     {
34         printf("%d",ans[i]);
35         if (i!=out) printf(" ");
36     }
37     printf("
");
38     out=0;
39     for (int i=1;i<=n+m;i++)
40     {
41         long long Max=0,maxj=0;
42         for (int j=1;j<=3;j++)
43             if (head[j]<=tail[j]&&q[j][head[j]][0]+(m-q[j][head[j]][1])*Q>Max) Max=q[j][head[j]][0]+(m-q[j][head[j]][1])*Q,maxj=j;
44         if (i%t==0) ans[++out]=Max;
45         head[maxj]++;
46     }
47     for (int i=1;i<=out;i++)
48     {
49         printf("%d",ans[i]);
50         if (i!=out) printf(" ");
51     }
52     printf("
");
53 }
原文地址:https://www.cnblogs.com/fengzhiyuan/p/7537844.html