【NOIP2016】蚯蚓

这是一道基础数据结构的综合题,思考量较大,但是实现简单。

我们考虑建立三个队列,分别存储原始长度、切开后第一段的长度、第二段长度。显然,这三个队列是非严格单调下降的,对于每个时刻,将要切开的蚯蚓即为三个队列队头的最大值。另外,我们用一个变量delta表示整个集合的偏移值,即队列中的长度+delta=实际长度。这样经过一次操作,delta+=q,即可实现对整个集合的加减。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 typedef long long ll;
 6 inline int read() {
 7     int ret=0,f=1;
 8     char c=getchar();
 9     while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
10     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
11     return ret*f;
12 }
13 using namespace std;
14 #define p u/v
15 int n,m,q,u,v,t;
16 ll q1[10000011],q2[10000011],q3[10000011];
17 int head1=1,head2=1,head3=1,tail1,tail2,tail3;
18 ll find(int x) {
19     ll r1=-1,r2=-1,r3=-1,r=-1;
20     if(head1<=tail1) r1=q1[head1]+x*q;
21     if(head2<=tail2) r2=q2[head2]+x*q;
22     if(head3<=tail3) r3=q3[head3]+x*q;
23     r=max(max(r1,r2),r3);
24     if(r==r1) head1++;
25     else if(r==r2) head2++;
26     else if(r==r3) head3++;
27     return r;
28 }
29 int main() {
30     n=read(); m=read(); q=read(); u=read(); v=read(); t=read();
31     tail1=n;
32     for(int i=1;i<=n;i++) {
33         q1[i]=read();        
34     }
35     sort(q1+1,q1+n+1);
36     reverse(q1+1,q1+n+1);
37     for(int i=1;i<=m;i++) {
38         ll ret=find(i-1);
39         if(i%t==0) printf("%lld ",ret);
40         ll n1=ret*p;
41         ll n2=ret-n1;
42         q2[++tail2]=n1-i*q;
43         q3[++tail3]=n2-i*q;
44     }
45     puts("");
46     for(int i=1;i<=n+m;i++) {
47         ll ret=find(m);
48         if(i%t==0) printf("%lld ",ret);
49     }
50     return 0;
51 }
AC Code
原文地址:https://www.cnblogs.com/shl-blog/p/10658851.html