题意:本题中,我们将用符号
蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。
蛐蛐国里现在共有
每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只(如有多个则任选一个)将其切成两半。神刀手切开蚯蚓的位置由常数
蛐蛐国王知道这样不是长久之计,因为蚯蚓不仅会越来越多,还会越来越长。蛐蛐国王决定求助于一位有着洪荒之力的神秘人物,但是救兵还需要
蛐蛐国王希望知道这
秒内,每一秒被切断的蚯蚓被切断前的长度(有 个数); 秒后,所有蚯蚓的长度(有 个数)。
蛐蛐国王当然知道怎么做啦!但是他想考考你……
算法一
考虑
算法二
考虑
于是我们就可以像线段树一样,打一个
对于每一秒:
- 取出集合中最大值
, 。 - 把
和 插入集合。 。
重复
算法三
因为
又因为
得到
上面的意义是,若
我们可以建立三个队列
code:
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
queue<long long> a;
queue<long long> b;
queue<long long> c;
bool cmp(long long a,long long b)
{
return a>b;
}
long long n,m,q,u,v,t,x,y;
long long s[101010];
int main()
{
scanf("%lld%lld%lld%lld%lld%lld",&n,&m,&q,&u,&v,&t);
for(int i=1;i<=n;i++)
scanf("%lld",&s[i]);
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++)
a.push(s[i]);
for(int i=1;i<=m;i++)
{
long long maxx=-1<<30;
long long p;
if(!a.empty())
if(a.front()>maxx)
{
maxx=a.front();
p=1;
}
if(!b.empty())
if(b.front()>maxx)
{
maxx=b.front();
p=2;
}
if(!c.empty())
if(c.front()>maxx)
{
maxx=c.front();
p=3;
}
if(p==1)
a.pop();
else if(p==2)
b.pop();
else if(p==3)
c.pop();
maxx+=(i-1)*q;
x=maxx*u/v;
y=maxx-x;
if(!(i%t))
printf("%lld ",maxx);
b.push(x-i*q);
c.push(y-i*q);
}
printf("\n");
long long r=1;
while(r)
{
long long maxx=-1<<30,p;
if(a.empty()&&b.empty()&&c.empty())
break;
if(!a.empty())
if(a.front()>maxx)
{
maxx=a.front();
p=1;
}
if(!b.empty())
if(b.front()>maxx)
{
maxx=b.front();
p=2;
}
if(!c.empty())
if(c.front()>maxx)
{
maxx=c.front();
p=3;
}
if(p==1)
a.pop();
else if(p==2)
b.pop();
else if(p==3)
c.pop();
if(r%t==0)
printf("%lld ",maxx+m*q);
r++;
}
return 0;
}