《算法竞赛进阶指南》0x12 队列 NOIP2016 蚯蚓

题目链接:https://www.acwing.com/problem/content/135/

可以证明每次切断的两段序列也是分别递减的,使用一个优先队列维护n个输入值的最大值,以及两个本来就有序的队列维护切断的两个序列即可。

注意本题需要使用longlong数据精度。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f3f3f3f3f;
priority_queue<ll> pq;
queue<ll> q1,q2;
int n,m,q,u,v,t;
int main (){
    cin>>n>>m>>q>>u>>v>>t;
    for(int i=1;i<=n;i++){
        ll x;
        scanf("%d",&x);
        pq.push(x);
    }
    ll delta=0;
    for(int i=1;i<=m;i++){
        ll maxx=-inf;
        int f=-1;
        if(!pq.empty() && pq.top()>maxx){//取出三个队列中最大的数 
            f=1,maxx=pq.top();
        }
        if(!q1.empty() && q1.front()>maxx){
            f=2,maxx=q1.front();
        }
        if(!q2.empty() && q2.front()>maxx){
            f=3,maxx=q2.front();
        }
        if(f==1)pq.pop();
        else if(f==2)q1.pop();
        else q2.pop();
        maxx+=delta;
        if(f==-1)cout<<"-1"<<endl;
        q1.push(maxx*u/v-delta-q);
        q2.push(maxx-maxx*u/v-delta-q);
        delta+=q;
        if(!(i%t))printf("%lld ",maxx);
    }
    cout<<endl; 
    for(int i=1;i<=n+m;i++){
        ll maxx=-inf;
        int f=-1;
        if(!pq.empty() && pq.top()>maxx){//取出三个队列中最大的数 
            f=1,maxx=pq.top();
        }
        if(!q1.empty() && q1.front()>maxx){
            f=2,maxx=q1.front();
        }
        if(!q2.empty() && q2.front()>maxx){
            f=3,maxx=q2.front();
        }
        if(f==1)pq.pop();
        else if(f==2)q1.pop();
        else q2.pop();
        maxx+=delta;
        if(!(i%t))printf("%lld ",maxx);
    }
    cout<<endl;
}

 

posted @ 2020-06-17 12:11  WA自动机~  阅读(164)  评论(0编辑  收藏  举报