[NOIP2016 提高组] 蚯蚓
单调队列优化.
#include<bits/stdc++.h> using namespace std; const int N=7e7+7; int n,m,l,u,v,t; int a[N],p1[N],p2[N]; priority_queue<int > q; double p; //我们要砍的目标,即最长的那条 int pos,sum; //头尾 int had,had1,had2; int til,til1,til2; //我们要求降序,即从长到短砍 bool cmp(int x,int y) { return x>y; } //相当于有3个队 int main() { ios::sync_with_stdio(false); cin>>n>>m>>l>>u>>v>>t; p=(double)u/v; //需要自己算比例 for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n,cmp); til=n;//开始全在a had=had1=had2=1; for(int i=1;i<=m;i++) { //找蚯蚓 if(had>til) {//发现空了,从1和2中找最大的 if(p1[had1]>p2[had2]) pos=p1[had1++]; else pos=p2[had2++]; } else if(a[had]>=p1[had1]&&a[had]>=p2[had2]) {//a的最长 pos=a[had]; had++; } else if(p1[had1]>=p2[had2]&&a[had]<=p1[had1]) {//1的最长 pos=p1[had1]; had1++; } else {//2的最长 pos=p2[had2]; had2++; } pos+=sum; int f1=floor(p*(double)pos),f2=pos-f1; sum+=l; //总共增加了多少长度 f1-=sum; //切开的其他增加sum,相当于切开的减少sum,最后输出时加上sum f2-=sum; //切掉的放进队列里 p1[++til1]=f1; p2[++til2]=f2; if(!(i%t)) cout<<pos<<' '; } cout<<endl; //将3的里面的蚯蚓全都放进pri_que for(int i=had;i<=til;i++) q.push(a[i]); for(int i=had1;i<=til1;i++) q.push(p1[i]); for(int i=had2;i<=til2;i++) q.push(p2[i]); for(int i=1;!q.empty();i++) { if(!(i%t))//排名 cout<<q.top()+sum<<' '; //之前欠下的长度 记得加上 q.pop(); } return 0; }