【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 }