题目:
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;
}