洛谷 2827 [NOIP2016] 蚯蚓 队列模拟

来源:互联网 发布:连江有淘宝培训班吗 编辑:程序博客网 时间:2024/05/22 17:26

题目:

https://www.luogu.org/problemnew/show/2827

首先一个蚯蚓被切割后,其他蚯蚓会增加q => 这个蚯蚓-q;
每次操作将此蚯蚓-q,然后最后统一+q * m即可;

85分暴力:
用堆模拟就行了;O(m log n)

100分正解:
O(n log n + m)
三个单调队列维护,第一个存初始蚯蚓,第二个存切割后的第一段,第三个存切割后的第二段,这是单调递减的,因为前面在切割前必然大于后面的,所以切割后也大于后面的;

注意inf需要赋为MAX int;

暴力:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;priority_queue<int>Q;int n,m,q,t,x,delta,num,cnt,tot,u1,u2,S;int ans[6000001];double u,v;void solve(){    cin>>n>>m>>q>>u>>v>>t;    for(int i=1;i<=n;i++) x=read(),Q.push(x);    for(int i=1;i<=m;i++)    {        S=Q.top();        Q.pop();        if(i % t==0) ans[++num]=S+tot;        u1=(S+tot)*u/v,u2=(S+tot)-u1;        Q.push(u1-q-tot),Q.push(u2-q-tot);        tot+=q;    }    for(int i=1;i<=num;i++) printf("%d ",ans[i]);    cout<<'\n';    while(!Q.empty())    {        S=Q.top();        Q.pop(),cnt++;        if(cnt % t==0) printf("%d ",S+tot);    }    return;}int main(){    solve();    return 0;}

正解:

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<queue>using namespace std;queue<int>Q[4];int n,m,t,q,p,tot,inf=2147483642;double u,v;int a[1000001];bool cmp(int a,int b){    return a>b;}int get(){    int ans=0,a=-inf,b=-inf,c=-inf;    if(!Q[1].empty()) a=Q[1].front();    if(!Q[2].empty()) b=Q[2].front();    if(!Q[3].empty()) c=Q[3].front();    if((a>b && a>c) || (a==b && a>c) || (a==c && a>b))        ans=Q[1].front(),Q[1].pop();    else if((b>a && b>c) || (b==c && b>a))        ans=Q[2].front(),Q[2].pop();    else if(c>a && c>b)        ans=Q[3].front(),Q[3].pop();    else if(c==a && c==b)        ans=Q[3].front(),Q[3].pop();    return ans;}void solve(){    cin>>n>>m>>q>>u>>v>>t;    for(int i=1;i<=n;i++) scanf("%d",&a[i]);    sort(a+1,a+n+1,cmp);    for(int i=1;i<=n;i++) Q[1].push(a[i]);    for(int i=1;i<=m;i++)    {        int S=get();        if(i % t == 0) printf("%d ",S+tot);        int u1=(S+tot)*u/v,u2=S+tot-u1;        Q[2].push(u1-tot-q),Q[3].push(u2-tot-q);        tot+=q;    }    cout<<'\n';    for(int i=1;i<=m+n;i++)    {        int S=get();        if(i % t==0) printf("%d ",S+tot);    }    return;}int main(){    solve();    return 0;}
原创粉丝点击