B: 蚯蚓
时间限制: 1 Sec 内存限制: 512 MB题目描述
本题中,我们将用符号
L
c
J
表示对
c
向下取整,例如:
L
3
.
0
J
=
L
3
.
1
J
=
L
3
.
9
J
=
3
。
蛐蛐国
最近
蚯蚓成
灾
了
!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。
蛐
蛐
国
里现
在
共
有
n
只蚯蚓
(
n
为
正
整
数)。每只蚯蚓拥有长度,我们设第
i
只
蚯蚓的长度为
ai
(i
=
1
,
2
,...,
n
)
,并保证所有的长度都是
非负
整数(即:可能存在长度为
0
的蚯蚓)。
每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只(如有多个则任选一
个)将其切成两半。神刀手切开蚯蚓的位置由常数
p
(是满足
0
<
p
<
1
的有理数)决定,设这只蚯蚓长度为
x
,神刀手会将其切成两只长度分别为[
px]
和
x
−[
px]
的蚯蚓([]表示下取整)
。
特殊地,如果这两个数的其中一个等于
0
,
则这个长度为
0
的蚯蚓也会被保留。此外,除了刚刚产生的两只新蚯蚓,其余蚯蚓的长度都会增加
q
(是一个非负整常数)。
蛐蛐国
王知
道这样
不是
长久
之
计
,
因为蚯
蚓不
仅会越
来
越
多
,
还会
越
来
越
长
。蛐蛐国王决定求助于一位有着洪荒之力的神秘人物,但是救兵还需要
m
秒才能到来
......
(
m
为非负整数)蛐蛐国王希望知道这
m
秒内的战况。
具体来说,他希望知道:
l
m
秒
内
,
每一秒被切断的蚯蚓被切断前的长度(有
m
个数);
l
m
秒后,所有蚯蚓的长度(有
n
+
m
个数)。
蛐蛐国王当然知道怎么做啦!但是他想考考你
.....
.
输入
第一行包含六个整数
n
,
m
,
q
,
u
,
v
,
t
,
其中:
n
,
m
,
q
的意义见【问题描述】;
u
,
v
,
t
均为正整数;你需要自己计算
p
=
u
/
v
(保证
0
<
u
<
v
)
;
t
是输
出参数,其含义将会在【输出格式】中解释。
第二行包含
n
个非负整数,为
a
1
,
a
2
,
...,
an
,即初始时
n
只蚯蚓的长度。
同一行中相邻的两个数之间,恰好用一个空格隔开。
保证
1
≤
n
≤
105
,
0
≤
m
≤
7
×
106
,
0
<
u
<
v
≤
109
,
0
≤
q
≤
200
,
1
≤
t
≤
71
,
0
≤
ai
≤
108
。
输出
第一行输出[m/t]个整数,按时间顺序,依次输出第
t
秒
,
第
2t
秒,第
3t
秒,
......
被切
断蚯蚓(在被切断前)的长度。
第二行输出[(n+m)/t]
个整数,输出
m
秒后蚯蚓的长度:需要按从大到小的顺序,
依次输出排名第
t
,第
2t
,第
3t
,
......
的长度。
同一
行
中相邻
的两
个数
之
间
,
恰好用
一个
空格
隔
开
。
即
使
某
一行
没
有
任
何数
需
要输出,你也应输出一个空行。
请阅读样例来更好地理解这个格式。
样例输入
3 7 1 1 3 1 3 3 2 3 7 1 1 3 2 3 3 2 3 7 1 1 3 9 3 3 2
样例输出
3 4 4 4 5 5 6 6 6 6 5 5 4 4 3 2 2 4 4 5 6 5 4 3 2 2
提示
【样例 1说明】
在神刀手到来前:
3
只蚯蚓的长度为
3,3,2
。
1秒后:一只长度为3的蚯蚓被切成了两只长度分别为1和2的蚯蚓,其余蚯蚓的长度增加了1。最终4只蚯蚓的长度分别为(1,2),4,3。括号表示这个位置刚刚有一只蚯蚓被切断。
2秒后:一只长度为4的蚯蚓被切成了1和3。5只蚯蚓的长度分别为:2,3,(1,3),4。
3秒后:一只长度为4的蚯蚓被切断。6只蚯蚓的长度分别为:3,4,2,4,(1,3)。
4秒后:一只长度为4的蚯蚓被切断。7只蚯蚓的长度分别为:4,(1,3),3,5,2,4。
5秒后:一只长度为5的蚯蚓被切断。8只蚯蚓的长度分别为:5,2,4,4,(1,4),3,5。
6秒后:一只长度为5的蚯蚓被切断。9只蚯蚓的长度分别为:(1,4),3,5,5,2,5,4,6。
7秒后:一只长度为6的蚯蚓被切断。10只蚯蚓的长度分别为:2,5,4,6,6,3,6,5,(2,4)。
所以,7秒内被切断的蚯蚓的长度依次为3,4,4,4,5,5,6。7秒后,所有蚯蚓长度从大到小排序为6,6,6,5,5,4,4,3,2,2。
【样例 2说明】
这个数据中只有
t
=
2
与上个数据不同。
只需在每行都改为每两个数输出一个数即可。
虽然第一行最后有一个
6
没有被输出,但是第二行仍然要重新从第二个数再开始输出。
【样例
3
说明】
这个数据中只有
t
=
9
与上个数据不同。
注意第一行没有数要输出,但也要输出一个空行。
【子任务】
测试点
1~3
满足
m
=
0
。
测试点
4~7
满足
n
,
m
≤
1
,
000
。
测试点
8~14
满足
q
=
0
,其中测试点
8
∼
9
还满足
m
≤
1
05
。
测试点
15~18
满足
m
≤
3
×
10
5
。
测试点
19~20
没有特殊的约定,参见原始的数据范围。
测试点
1~12
,
15~16
还满足
v
≤
2
,这意味着
u
,
v
的唯一
可
能的取
值
是
u
=
1
,
v
=
2
,即
p
=
0
.
5
。这可能会对解决问题有特殊的帮助。
每个测试点的详细数据范围见下表。
测试点
|
n
|
m
|
t
|
ai
|
v
|
q
|
1
|
=1
|
=0
|
=1
|
≤ 106
|
≤ 2
|
= 0
|
2
|
=103
| |||||
3
|
=105
| |||||
4
|
= 1
|
= 103
| ||||
5
|
=103
| |||||
6
|
=1
|
≤ 200
| ||||
7
|
=103
| |||||
8
|
=
5
×
104
|
=
5
×
104
|
= 0
| |||
9
|
=105
|
=105
|
=2
| |||
10
|
=
2
×
106
|
=21
| ||||
11
|
=
2
.
5
×
106
|
=26
| ||||
12
|
=
3
.
5
×
106
|
=36
|
≤ 107
| |||
13
|
=
5
×
106
|
=51
|
≤ 109
| |||
14
|
=
7
×
106
|
=71
|
≤ 108
| |||
15
|
=
5
×
104
|
=
5
×
106
|
=1
|
≤ 2
|
≤ 200
| |
16
|
=
1
.
5
×
106
|
=2
| ||||
17
|
=105
|
=105
|
=3
|
≤ 109
| ||
18
|
=
3
×
105
|
=4
| ||||
19
|
=
3
.
5
×
106
|
=36
| ||||
20
|
=
7
×
106
|
=71
|
我们可以先将蚯蚓从大到小排序,然后建三个单调递减队列分别表示原来的蚯蚓,分割下来的长蚯蚓,短蚯蚓。每次取队首的最大元素进行处理。
Code:
#include <cstdio>
#include <algorithm>
using namespace std;
long long n,m,q,u,v,t,k,k1,k2;
long long a[100005],b[7000005],c[7000005],fa=1,fb=1,fc=1,rb,rc;
bool cmp(int x,int y)
{
return x>y;
}
long long choose(int i)
{
long long x1,x2,x3,xx;
x1=x2=x3=-1;
if (fa<=n) x1=a[fa]+(i-1)*q;
if (fb<=rb) x2=b[fb]+(i-1)*q;
if (fc<=rc) x3=c[fc]+(i-1)*q;
xx=max(x1,max(x2,x3));
if (xx==x1)fa++; else
if (xx==x2)fb++; else fc++;
return(xx);
}
int main()
{
scanf("%d%d%d%d%d%d",&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<=m;i++)
{
k=choose(i);
if (i%t==0)
{
if(i+t>m)printf("%d",k);
else printf("%d ",k);
}
k1=k*u/v;
k2=min(k1,k-k1);
k1=k-k2;
b[++rb]=k1-i*q;
c[++rc]=k2-i*q;
}
printf("\n");
for (int i=1; i<=n+m; i++)
{
k=choose(m+1);
if (i%t==0)
{
if(i+t>n+m)printf("%d",k);
else printf("%d ",k);
}
}
return 0;
}