NC16430 [NOIP2016]蚯蚓

题目

题目描述

本题中,我们将用符号 \(\lfloor c \rfloor\) 表示对 c 向下取整,例如:\(\lfloor 3.0 \rfloor = \lfloor 3.1 \rfloor = \lfloor 3.9 \rfloor = 3\) 。

蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。

蛐蛐国里现在共有 n 只蚯蚓(n 为正整数)。每只蚯蚓拥有长度,我们设第 i 只蚯蚓的长度为 \(a_i (i = 1, 2, \ldots , n)\),并保证所有的长度都是非负整数(即:可能存在长度为 0 的蚯蚓)。

每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只(如有多个则任选一个)将其切成两半。神刀手切开蚯蚓的位置由常数 p(是满足 0 < p < 1 的有理数)决定,设这只蚯蚓长度为 x,神刀手会将其切成两只长度分别为 \(\lfloor px \rfloor\) 和 \(x - \lfloor px \rfloor\) 的蚯蚓。特殊地,如果这两个数的其中一个等于 0,则这个长度为 0 的蚯蚓也会被保留。此外,除了刚刚产生的两只新蚯蚓,其余蚯蚓的长度都会增加 q(是一个非负整常数)。

蛐蛐国王知道这样不是长久之计,因为蚯蚓不仅会越来越多,还会越来越长。蛐蛐国王决定求助于一位有着洪荒之力的神秘人物,但是救兵还需要 m 秒才能到来 ……(m 为非负整数)

蛐蛐国王希望知道这 m 秒内的战况。具体来说,他希望知道:

·m 秒内,每一秒被切断的蚯蚓被切断前的长度(有 m 个数);

·m 秒后,所有蚯蚓的长度(有 n + m 个数)。

蛐蛐国王当然知道怎么做啦!但是他想考考你 ……

输入描述

第一行包含六个整数 n,m,q,u,v,t,其中:n,m,q 的意义见「题目描述」;u,v,t 均为正整数,你需要自己计算 \(p = \frac{u}{v}\)(保证 0 < u < v);t 是输出参数,其含义将会在「输出描述」中解释。

第二行包含 n 个非负整数,为 a1, a2, ..., an,即初始时 n 只蚯蚓的长度。

同一行中相邻的两个数之间,恰好用一个空格隔开。

保证 \(1 ≤ n ≤ 10^5,0 < m < 7 x 10^6,0 < u < v < 10^9,0 ≤ q ≤ 200,1 < t < 71,0 < a_i < 10^8\)。

输出描述

第一行输出 \(\lfloor \frac{m}{t} \rfloor\) 个整数,按时间顺序,依次输出第 t 秒,第 2t 秒,第 3t 秒 …… 被切断蚯蚓(在被切断前)的长度。

第二行输出 \(\lfloor \frac{(n+m)}{t} \rfloor\)个整数,输出 m 秒后蚯蚓的长度;需要按从大到小的顺序,依次输出排名第 t,第 2t,第 3t …… 的长度。

同一行中相邻的两个数之间,恰好用一个空格隔开。即使某一行没有任何数需要输出,你也应输出一个空行。

请阅读样例来更好地理解这个格式。

示例1

输入

3 7 1 1 3 1
3 3 2

输出

3 4 4 4 5 5 6
6 6 6 5 5 4 4 3 2 2

说明

在神刀手到来前: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

输入

3 7 1 1 3 2
3 3 2

输出

4 4 5
6 5 4 3 2

说明

这个数据中只有 t = 2 与上个数据不同。只需在每行都改为每两个数输出一个数即可。

虽然第一行最后有一个 6 没有被输出,但是第二行仍然要重新从第二个数再开始输出。

备注

\(1 ≤ n ≤ 10^5, 0 ≤ m ≤ 7 \times 10^6, 1 ≤ t ≤ 71, 0 ≤ a_i ≤ 10^8, 1 ≤ v ≤ 10^9, 0 ≤ q ≤ 200\)

题解

思路

知识点:队列。

这道题用优先队列会被卡,而用队列即可维护单调性,不需要优先队列。

首先按从大到小排序,设置一个队列存放原来的蚯蚓,两个队列分别存放分割的两部分。由于分割比例相同,而蚯蚓是从大到小选的,则分割的两部分一定能各自递减排列,只需要分别放入两个新队列的队尾即可。

每次三个队列队头找最大值,为了方便标记,一开始用队列数组创建三个队列,先从三个队列中找到任意一个非空队列标记上,然后再在三个队列中找到非空队列的队头最大值并标记,随后就得到了最大的队头所在队列的下标。

因为每次所有蚯蚓,除了这次分割的蚯蚓,都长度增加 \(q\) ,一个一个加显然不合理,注意到 \(q\) 和时间有关,那么如果当前时间是第 \(i\) 秒蚯蚓原长是 \(len\),假设蚯蚓没有切割过,那么长度就为 \(len + (i-1)q\) ,\(i-1\) 是因为第 \(i\) 秒只长了 \(i-1\) 秒,第 \(i\) 秒后才是 \(i\) 。

现在考虑分割的蚯蚓如何计算,因为分割需要用真实长度,因此必须先计算出真实长度 \(x\) ,然后计算出新蚯蚓长度 $l = \lfloor x\cdot \frac{u}{v} \rfloor $ ,\(r = l - x\) ,前者可以不用浮点运算,先计算 \(xu\) 再整除 \(v\) ,记得开 \(long \ long\) ,如此得到新蚯蚓的真实长度。但是,真实长度是不兼容我们对新增长度的优化的,因为如此新蚯蚓的增长时间就不一样了,有两种方案:第一种,记录新蚯蚓产生时间是第 \(k\) 秒,那么第 \(i\) 秒长度就为 \(len + (i-1-k)q\) ,并非 \(k-1\) 因为新切的蚯蚓在第 \(k\) 秒后也是不会增长的,因此实际增长时间要从第 \(k+1\) 秒开始计算到之前第 \(i\) 秒,一共 \(i - k - 1\) 秒;第二种,计算新蚯蚓的假想初始长度,即假设新蚯蚓一开始就存在,求出在第 \(i\) 秒后(因为第 \(i\) 秒之前切完到第 \(i\) 秒后长度不变)增长到这个长度的初始长度,这样就能兼容一开始用当前时间计算长度的方式了,那么假想初始长度就是 \(len - i\cdot q\) ,因为增长了 \(i\) 秒一共 \(i\cdot q\) 的长度。最后把长度分别放入两个新队列里。

因为不是每秒都输出,用一个计数器 \(tcnt\),记录下一次输出的时间是 \(t\) 的几倍,\(i == tcnt \cdot t\) 时输出第 \(tcnt \cdot t\) 秒的切割蚯蚓的长度。

最后不用 \(sort\) 排序,因为三队列都是有序的,直接归并即可,输出方式同上。

时间复杂度 \(O(n \log n +m)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

int a[100007];

int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m, q, u, v, t;
cin >> n >> m >> q >> u >> v >> t; for (int i = 0;i < n;i++) cin >> a[i];
sort(a, a + n, [&](int a, int b) {return a > b;}); queue<int> Q[3];
for (int i = 0;i < n;i++) Q[0].push(a[i]); int tcnt = 1;///计时器
for (int i = 1;i <= m;i++) {///用最初长度加增长长度代表真实长度
int pos = 0;
///找到最大的蚯蚓
for (int j = 0;j < 3;j++)
if (!Q[j].empty()) pos = j;
for (int j = 0;j < 3;j++)
if (!Q[j].empty() && Q[pos].front() < Q[j].front()) pos = j; int x = Q[pos].front() + (i - 1) * q;///第i秒的真实长度
if (i == tcnt * t)cout << x << ' ', tcnt++;
Q[pos].pop();
int l = 1LL * x * u / v;///分割后的真实长度
int r = x - l;
///分割的假设最初长度,计算增长长度公式就能统一了
Q[1].push(l - i * q);///第i秒后长度为l,因此初始长度是 l - i*q
Q[2].push(r - i * q);///同上
}
cout << '\n';
tcnt = 1;
for (int i = 1;i <= n + m;i++) {///三路归并
int pos = 0;
for (int j = 0;j < 3;j++)
if (!Q[j].empty()) pos = j;
for (int j = 0;j < 3;j++)
if (!Q[j].empty() && Q[pos].front() < Q[j].front()) pos = j;
if (i == tcnt * t) cout << Q[pos].front() + m * q << ' ', tcnt++;
Q[pos].pop();
}
return 0;
}

NC16430 [NOIP2016]蚯蚓的更多相关文章

  1. [Noip2016]蚯蚓 D2 T2 队列

    [Noip2016]蚯蚓 D2 T2 Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯 ...

  2. 【BZOJ】4721: [Noip2016]蚯蚓 / 【洛谷】P2827 蚯蚓(单调队列)

    Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮 ...

  3. 【bzoj4721】[Noip2016]蚯蚓

    题目描述 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓.蛐 ...

  4. 【uoj264】 NOIP2016—蚯蚓

    http://uoj.ac/problem/264 (题目链接) 题意 n条蚯蚓,时间为m.每单位时间要可以将最长的蚯蚓切成len/2和len-len/2两份,长度为0的蚯蚓不会消失,因为每单位时间所 ...

  5. BZOJ4721 [Noip2016]蚯蚓

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  6. [NOIp2016] 蚯蚓

    类型:单调队列 传送门:>Here< 题意:有$N$只蚯蚓,每秒都会伸长$q$.每一次都会有人选出最长的一条切成两半,长度分别是$\left \lfloor px \right \rflo ...

  7. luogu2827 [NOIp2016]蚯蚓 (模拟)

    可以直观地想到用优先队列来做,但数据范围是O(n)的 然后我们发现,因为我们每次挑出来的蚯蚓是单调的,所以把每个切成两段后,那两段也是对应单调的 也就是说,算上最一开始的蚯蚓,我们一共维护三个队列,三 ...

  8. [NOIp2016]蚯蚓 (队列)

    #\(\color{red}{\mathcal{Description}}\) LInk 这道题是个\(zz\)题 #\(\color{red}{\mathcal{Solution}}\) 我们考虑如 ...

  9. 【bzoj4721】[Noip2016]蚯蚓 乱搞

    题目描述 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓.蛐 ...

随机推荐

  1. Jx.Cms开发笔记(五)-文章编辑页面标签设计

    标签页的样子 设计思路 与其他输入框一样,存在一个Label标签,由于这里不像其他输入框一样可以直接使用Row标签,所以这里需要额外增加. 使用Tag组件显示所有的标签,我们在Blazor 组件库 B ...

  2. AQS源码阅读

    简介 AQS 全程为 AbstractQueuedSynchronizer , 在 java.util.concurrent.locks包下的一个抽象类. 类的具体作用以及设计在开始类描述信息里面就有 ...

  3. kali 安装 docker

    添加密钥 信任 浙大更新源 curl -fsSL http://mirrors.zju.edu.cn/docker-ce/linux/debian/gpg | sudo apt-key add - t ...

  4. SpringBoot项目刚刚创建就报异常,Failed to configure a DataSource: 'url' attribute is not specified and no embedded 的解决办法

    错误信息: Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedde ...

  5. JDBC:加载数据库驱动、连接数据库(详细讲解)

    加载数据库驱动: 1)由于Java是一个纯面向对象语言,任何事物在其中都必须抽象成类或者类对象,数据库也不例外,JDBC同样也把数据库抽象成面向对象的结构: 2)JDBC将整个数据库驱动器在底层抽象成 ...

  6. .NET混合开发解决方案10 WebView2控件调用网页JS方法

    系列目录     [已更新最新开发文章,点击查看详细] WebView2控件应用详解系列博客 .NET桌面程序集成Web网页开发的十种解决方案 .NET混合开发解决方案1 WebView2简介 .NE ...

  7. python之函数的进阶

    1.名称空间: 定义:用来存放名字的(变量,函数名,类名,引入的模块名) 分类: 内置名称空间:python解释器提供好的一些内置内容 全局名称空间:py文件中自己写的变量 局部名称空间:执行函数时会 ...

  8. (AAAI2020 Yao) Graph Few-shot Learning via knowledge transfer

    22-5-13 seminar上和大家分享了这篇文章 [0]Graph few-shot learning via knowledge transfer 起因是在MLNLP的公众号上看到了张初旭老师讲 ...

  9. 645. Set Mismatch - LeetCode

    Question 645. Set Mismatch Solution 思路: 遍历每个数字,然后将其应该出现的位置上的数字变为其相反数,这样如果我们再变为其相反数之前已经成负数了,说明该数字是重复数 ...

  10. 146_ACCESS之HR招聘信息管理_64位

    焦棚子的文章目录 点击下载附件 一.背景: 最近把之前做的一个HR招聘信息管理工具翻新了下,有需要的朋友可以自取,主要想解决的问题是多人在跟进人员招聘的时候信息的不对称,这样下来的就可以及时的看到整个 ...