首先我们给蚯蚓从大到小排序。然后可以发现,每次切出来的蚯蚓中,长的那写按切的顺序形成非上升序列,短的那些也如此。那么我们维护3个单调队列即可(原始蚯蚓也算一个单调队列),每次找三个队列队首元素最大的那个,把这个蚯蚓切掉,然后分别插入两个单调队列中。最后也按照这样每次找出最大的,按要求把该输出的输出即可。由于最后有n+m只蚯蚓,所以这样的时间复杂度O(n+m)。
1 #include<set> 2 #include<map> 3 #include<list> 4 #include<queue> 5 #include<stack> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<vector> 10 #include<bitset> 11 #include<memory> 12 #include<utility> 13 #include<cstdio> 14 #include<sstream> 15 #include<iostream> 16 #include<cstdlib> 17 #include<cstring> 18 #include<algorithm> 19 using namespace std; 20 21 int n,m,q,u,v,g,del; 22 long long a[1000005],b[4][7000005],h[5],t[5]; 23 24 int main(){ 25 scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&g); 26 for(int i=1;i<=n;i++){ 27 scanf("%lld",a+i); 28 } 29 sort(a+1,a+1+n); 30 for(int i=1;i<=n;i++){ 31 b[1][n-i+1]=a[i]; 32 } 33 h[1]=h[2]=h[3]=1; 34 t[1]=n; 35 t[2]=t[3]=0; 36 del=0; 37 for(int i=1;i<=m;i++){ 38 long long ans=-1<<30,num=0; 39 for(int j=1;j<=3;j++){ 40 if(h[j]<=t[j]&&b[j][h[j]]>ans){ 41 ans=b[j][h[j]]; 42 num=j; 43 } 44 } 45 if(i%g==0){ 46 printf("%lld ",ans+del); 47 } 48 h[num]++; 49 b[2][++t[2]]=(long long)(ans+del)*u/v-del-q; 50 b[3][++t[3]]=ans+del-(long long)(ans+del)*u/v-del-q; 51 del+=q; 52 } 53 printf(" "); 54 for(int i=1;i<=m+n;i++){ 55 long long ans=-1<<30,num=0; 56 for(int j=1;j<=3;j++){ 57 if(h[j]<=t[j]&&b[j][h[j]]>ans){ 58 ans=b[j][h[j]]; 59 num=j; 60 } 61 } 62 if(i%g==0){ 63 printf("%lld ",ans+del); 64 } 65 h[num]++; 66 } 67 return 0; 68 }