NOIP2016Day2T2-蚯蚓

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的蚯蚓被切成了两只长度分别为12的蚯蚓,其余蚯蚓的长度增加了1最终4蚯蚓的长度分(1,2),4,3。括号表示这个位置刚刚有一只蚯蚓被切断。

2秒后:一只长度为4的蚯蚓被切成了135只蚯蚓的长度分别为: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,67秒后,所有蚯蚓长度从大到小排序为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; 
} 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack-Oran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值