题干

本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3。蛐蛐国最近蚯蚓成灾了!隔壁跳蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮他们消灭蚯蚓。蛐蛐国里现在共有n只蚯蚓(n为正整数)。每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n),并保证所有的长度都是非负整数(即:可能存在长度为0的蚯蚓)。每一秒,神刀手会在所有的蚯蚓中,准确地找到最长的那一只(如有多个则任选一个)将其切成两半。神刀手切开蚯蚓的位置由常数p(是满足0<p<1的有理数)决定,设这只蚯蚓长度为x,神刀手会将其切成两只长度分别为[px]和x-[px]的蚯蚓。特殊地,如果这两个数的其中一个等于0,则这个长度为0的蚯蚓也会被保留。此外,除了刚刚产生的两只新蚯蚓,其余蚯蚓的长度都会增加q(是一个非负整常数)。蛐蛐国王知道这样不是长久之计,因为蚯蚓不仅会越来越多,还会越来越长。蛐蛐国王决定求助于一位有着洪荒之力的神秘人物,但是救兵还需要m秒才能到来......(m为非负整数)蛐蛐国王希望知道这m秒内的战况。具体来说,他希望知道:m秒内,每一秒被切断的蚯蚓被切断前的长度(有m个数)m秒后,所有蚯蚓的长度(有n+m个数)。蛐蛐国王当然知道怎么做啦!但是他想考考你......

Input

第一行包含六个整数n,m,q,u,v,t,其中:n,m,q的意义见问题描述;

u,v,t均为正整数;你需要自己计算p=u/v(保证0<u<v)t是输出参数,其含义将会在输出格式中解释。

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

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

保证1<=n<=10^5,0<m<7*10^6,0<u<v<10^9,0<=q<=200,1<t<71,0<ai<10^8。

Output

第一行输出[m/t]个整数,按时间顺序,依次输出第t秒,第2t秒,第3t秒……被切断蚯蚓(在被切断前)的长度。

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

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

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

Example

in:

3 7 1 1 3 1

3 3 2

out:

3 4 4 4 5 5 6

6 6 6 5 5 4 4 3 2 2

又要开始扯淡了...

完整的思路来源于这里:[膜拜大佬]: https://www.cnblogs.com/ljh2000-jump/p/6184271.html

很不错的博客,包括基本的一步步的思路和解释都写出来了。唯一接受不能的是代码,没有注释还好说,为毛要把所有循环都写在一行里啊!(╯‵□′)╯︵┻━┻

大家如果对部分分的实现有想法可以直接去看上面那篇博客,我这里直接着重介绍正解。(个人还是推荐大家去看一看的,毕竟真正考试的时候哪有这么容易想到正解╮(╯▽╰)╭)

首先,每次都要取出一个最大值来进行操作,我们第一时间想到的就是堆,当然这么大的数据我们能手写单调队列还是手写而且上面的博客里也提到了这点,况且对这道题而言也多费不了多少事。然后就是还有一个给所有蚯蚓都加上q的操作,直接加到每一个蚯蚓身上显然时间上不允许,所以我们考虑开一个全局的tmp储存蚯蚓长度的总改变量,在堆里面只储存原始值(当然我们肯定是要更新队首元素的),每次更新时取出最大值,加上tmp,得到真实值,算出两个新元素值,tmp加上q,两个新元素值减去tmp,丢入堆中。

那么我们最后为什么要用三个队列分别储存原始值、p×x和x-p×x呢?因为这三个队列各自具有单调性。

对于单调性的研究,我们能得出这个队列一定是不上升的(蚯蚓长度可能为0,所以不是单调递减),我们可以考虑如下:(这里直接考虑q为自然数的情况,省去了先从q=0考虑开始的步骤)

我们假设某一时刻队列中有一个最大值A,有一个值B,根据定义,B肯定是小于等于A的,此时A被切割成两个部分。然后经过了N轮切割,轮到B被切割了,我们再假设B被切割出来的部分比先前A切割出来的部分大,那么有:

  • A×p+N×q<(B+N×q)×p(只考虑乘以p的部分)
  • 那么展开一下得:A×p+N×q<B×p+N×q×p
  • 我们知道A>=B,而且p<1,那么显然上面的式子是矛盾的,则反证法可证出队列一定不上升

其实我们换个角度来理解,我们一直都在对最大的那条切切切,虽然从整体上看我们切去的肯定不如增长的长度多,但是增长的长度那是针对所有蚯蚓而言的啊。每条蚯蚓都是在同时增长相同的值,那么说明他们之间的相对长度都是永远不变的(假如我们不去切他),那么我们现在去切蚯蚓,即使不会使长度更短,起码也不会更长吧。

所以,根据上面的结论,我们分为三个单调队列来分别存储:原队列、p×x和x-p×x,这三个队列每单独一个拿出来都是保证不上升的。

小提醒:

由于题目中不是直接给出的p,而是通过给出分子分母要求我们自己计算p,来降低精度误差。在乘的时候需要开一个long long的临时变量,除完之后再转成int就可以了。其余的均可只开int。

ps:写的还是太着急了,有空我再更新更新。。。

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
const int maxn=7000000+10;
const ll inf=1ll<<60;
int m,n,q,t,tmp;
int qu[3][maxn],head[3],tail[3];//维护三个单调队列
ll u,v;
bool Cmp(int a,int b){
return a>b;
}
void Init(){
scanf("%d%d%d%d%d%d",&n,&m,&q,&u,&v,&t);
for(int i=1;i<=n;i++){
scanf("%d",&qu[0][i]);
}
sort(qu[0]+1,qu[0]+1+n,Cmp);
tmp=0;
head[0]=head[1]=head[2]=1;
tail[0]=n;//一开始所有蚯蚓都在第1队列里,我们把px都放入第2队列,x-px都放入第3队列
tail[1]=tail[2]=0;
}
void Solve(){
ll now;
int from,l1,l2,out=0;
bool flag=1;
for(int i=1;i<=m;i++){
now=-inf;//选取三个队列中的最大值
from=-1;
for(int j=0;j<=2;j++)
if(head[j]<=tail[j]){
if(qu[j][head[j]]>now){//更新最大值
now=qu[j][head[j]];
from=j;
}
}
now+=tmp;
out++;
if(out==t){//保证在t的整数倍输出
if(!flag) printf(" ");
flag=0;
printf("%lld",now);
out=0;
}
l1=now*u/v;
l2=now-l1;
head[from]++;
tmp+=q;
l1-=tmp,l2-=tmp;
qu[1][++tail[1]]=l1;//添加队列元素
qu[2][++tail[2]]=l2;
//printf("after %d s cut,tmp=%d\n",i,tmp);
}
printf("\n"); //以下为第二行输出
m+=n;out=0;flag=true;
for(int i=1;i<=m;i++) {
now=-inf; from=-1;
for(int j=0;j<3;j++)
if(head[j]<=tail[j]){
if(qu[j][head[j]]>now){
now=qu[j][head[j]];
from=j;
}
}
now+=tmp;
out++;
if(out==t) {
if(!flag) printf(" ");
flag=false;
printf("%lld",now);
out=0;
}
head[from]++;
}
}
int main(){
Init();
Solve();
return 0;
}

[Noip2016]蚯蚓 (单调队列)的更多相关文章

  1. [noip2016]蚯蚓<单调队列+模拟>

    题目链接:https://vijos.org/p/2007 题目链接:https://www.luogu.org/problem/show?pid=2827#sub 说实话当两个网站给出AC后,我很感 ...

  2. luogu 2827 蚯蚓 单调队列/优先队列

    易知可利用优先队列选取最大值: 但是通过分析可知,先取出的蚯蚓分开后仍然要比后分的长,所以可直接利用单调队列找队头即可,分三个单调队列,分别找未切割,切割,切割2三种情况 #include<bi ...

  3. 洛谷P2827 蚯蚓(单调队列)

    题意 初始时有$n$个蚯蚓,每个长度为$a[i]$ 有$m$个时间,每个时间点找出长度最大的蚯蚓,把它切成两段,分别为$a[i] * p$和$a[i] - a[i] * p$,除这两段外其他的长度都加 ...

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

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

  5. [Noip2016]蚯蚓 D2 T2 队列

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

  6. NOIP2016-D2-T2 蚯蚓(单调队列)

    构建三个单调队列(用STL),分别储存未切的蚯蚓,切后的第一段,切后的第二段,即可简单证明其单调性. 证明:设$q$为单调队列$\because a_1 \geqslant a_2 \geqslant ...

  7. 【uoj264】 NOIP2016—蚯蚓

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

  8. BZOJ4721 [Noip2016]蚯蚓

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

  9. [NOIp2016] 蚯蚓

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

随机推荐

  1. TZOJ Start

    描述 After the Online Round contest, we believe that you have already known how to write programs in A ...

  2. Python学习之温度转换实例分析篇

    #TempConvert.py Tempstr=input('请输入要转换的温度值:') if Tempstr[-1] in ['C','c']: F=1.8*eval(Tempstr[0:-1])+ ...

  3. 数据结构之链表(Linked list)

    说明:如果仔细阅读完全文后,可能感觉有些不统一,这里先说明下原因. 链表尾引用不统一:在介绍单链表时,只有一个链表首部的引用(head) 指向第一个节点.你看到后面关于双链表及循环列表时,除了指向第一 ...

  4. MySQL 8.0权限认证(下)

    MySQL 8.0权限认证(下)   一.设置MySQL用户资源限制   通过设置全局变量max_user_connections可以限制所有用户在同一时间连接MySQL实例的数量,但此参数无法对每个 ...

  5. sublime配置C++编译环境

    配置C++编译命令 { "file_regex": "^(..[^:]*):([0-9]+):?([0-9]+)?:? (.*)$", "workin ...

  6. python2.7 函数的参数学习

    1.默认参数 默认参数可以简化函数的调用. 设置默认参数时,有几点要注意: 一.必选参数在前,默认参数在后,否则Python的解释器会报错. 二.当函数有多个参数时,把变化大的参数放前面,变化小的参数 ...

  7. <OPTEE>Trusted Application结构分析

    最近又开始和Trusted Zone打起了交道,需要把Linaro开发的开源安全系统optee os移植到实验室的老板子上.不过导师要求我先开发一个应用,在普通环境和安全环境分别有一个程序,称为hos ...

  8. @gym - 100958J@ Hyperrectangle

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个大小为 \(l_1\times l_2 \dots l_ ...

  9. HTMLTestRunner生成html测试报告

    使用:把文件放到项目某个文件夹中,引入方式如下 import unittest import env import vendor.report.HTMLTestRunnerNew as HTMLTes ...

  10. 一篇文章搞懂filebeat(ELK)

    本文使用的filebeat是7.7.0的版本本文从如下几个方面说明: filebeat是什么,可以用来干嘛 filebeat的原理是怎样的,怎么构成的 filebeat应该怎么玩 一.filebeat ...