洛谷 P2827 蚯蚓 题解
每日一题 day32 打卡
Analysis
我们可以想一下,对于每一秒除了被切的哪一个所有的蚯蚓都增长Q米,我们来维护3个队列,队列1表示最开始的蚯蚓,队列2表示每一次被切的蚯蚓被分开的较长的那一部分,队列3表示每一次被切的蚯蚓被分开的较短的那一部分。
我们先把原序列排序,因为不管怎么切,先被切的蚯蚓分成的两部分一定比后切的蚯蚓分成的两部分大(较大的部分和较大的部分比较,较小的部分和较小的部分比较),所以我们可以省去每一秒增加每只蚯蚓的长度这个操作,转换成在查询砍那只蚯蚓时,把增加的长度算到蚯蚓的总长度上。
寻找每次砍哪一只蚯蚓就是在队列1、队列2、队列3的队头找一个算上增加的长度最大的蚯蚓,之后把他出队,切开的两部分分别进入队2、队3。
对于增量的计算我们可以按照蚯蚓在队列中的标号,因为队列1中的蚯蚓直到被切是一直处于一种增长状态,所以直接加上(当前时间-1) \* Q
就可以了,而对于队列2和队列3的蚯蚓,他的增长是从被切掉那一刻的下一秒开始的,所以他的增长量则是(当前时间-1-被切割的时间)\*Q
。
统计答案的时候把三个队列合并,排序输出就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<queue> 7 #define maxm 7000000+10 8 #define R register 9 using namespace std; 10 inline int read() 11 { 12 int x=0; 13 bool f=1; 14 char c=getchar(); 15 for(; !isdigit(c); c=getchar()) if(c=='-') f=0; 16 for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0'; 17 if(f) return x; 18 return 0-x; 19 } 20 inline void write(int x) 21 { 22 if(x<0){putchar('-');x=-x;} 23 if(x>9)write(x/10); 24 putchar(x%10+'0'); 25 } 26 int n,m,q,u,v,t,sum; 27 double p; 28 int fir[maxm],sec[maxm],thi[maxm]; 29 int head1,head2,head3,tail1,tail2,tail3; 30 priority_queue<int> que; 31 inline bool cmp(int x,int y){return x>y;} 32 inline int min_three(int x,int y,int z){return min(x,min(y,z));} 33 inline int max_three(int x,int y,int z){return max(x,max(y,z));} 34 int main() 35 { 36 n=read();m=read();q=read();u=read();v=read();t=read(); 37 for(R int i=1;i<=n;i++) fir[i]=read(); 38 p=(double)u/v; 39 sort(fir+1,fir+n+1,cmp); 40 tail1=n; 41 head1=head2=head3=1; 42 for(R int i=1;i<=m;i++) 43 { 44 int top=0; 45 if(head1>tail1) 46 { 47 if(sec[head2]>=thi[head3]) top=sec[head2],head2++; 48 else if(sec[head2]<thi[head3]) top=thi[head3],head3++; 49 } 50 else if(fir[head1]>=sec[head2]&&fir[head1]>=thi[head3]) top=fir[head1],head1++; 51 else if(sec[head2]>=fir[head1]&&sec[head2]>=thi[head3]) top=sec[head2],head2++; 52 else if(thi[head3]>=fir[head1]&&thi[head3]>=sec[head2]) top=thi[head3],head3++; 53 top+=sum; 54 int a=floor(p*(double)top); 55 int b=top-a; 56 a-=q;b-=q; 57 a-=sum;b-=sum; 58 sec[++tail2]=a; 59 thi[++tail3]=b; 60 if(i%t==0) 61 { 62 write(top); 63 putchar(' '); 64 } 65 sum+=q; 66 } 67 putchar('\n'); 68 for(R int i=min_three(head1,head2,head3);i<=max_three(tail1,tail2,tail3);i++) 69 { 70 if(i>=head1&&i<=tail1) que.push(fir[i]); 71 if(i>=head2&&i<=tail2) que.push(sec[i]); 72 if(i>=head3&&i<=tail3) que.push(thi[i]); 73 } 74 int vol=que.size(); 75 for(R int i=1;i<=vol;i++) 76 { 77 if(i%t==0) 78 { 79 write(que.top()+sum); 80 putchar(' '); 81 } 82 que.pop(); 83 } 84 return 0; 85 }
请各位大佬斧正(反正我不认识斧正是什么意思)