类型:单调队列

传送门:>Here<

题意:有$N$只蚯蚓,每秒都会伸长$q$。每一次都会有人选出最长的一条切成两半,长度分别是$\left \lfloor px \right \rfloor$和$x - \left \lfloor px \right \rfloor$ 询问每一秒最长的蚯蚓被切前的长度,以及$m$秒后每条蚯蚓的长度(从大到小排序)

解题思路

NOIp的subtask还是非常良心的。于是决定不看题解开始干……

看完题目,花了10分钟打了一个超级暴力模拟,35分get 然后发现有60分是$q=0$的情况……这不是就是一个裸的堆吗?打了15分钟,50分get(为什么只有50……) 然后想了很久没思路,瞟了一眼题解一眼就看到去减长度而不用管加,赶紧开始打调试近40分钟后85分get 然后就开始看题解打正解了……正解也调了20分钟左右 最终的AC代码再交一次竟然变成了90 又交一次变成了95 再交一次又100了……洛谷的评测机也不是很稳定啊,这题还是有点卡常

先来看看85分怎么拿。85分的写法在思想上还是很重要的——蚯蚓每秒增长$q$,可以看做是被切的蚯蚓减去$q$。因此我们可以维护一个堆,这样堆的内部就不需要反复更新。但是细节要注意,选择切割的蚯蚓长度应该拿真实的长度来算

然后来看正解。很容易发现,对于两条蚯蚓$x,y$,如果$x>y$,则$x$肯定会先被切掉。不妨设$x$被切掉以后变为$\{a_1, b_1\}$,$y$被切后变为$\{a_2, b_2\}$

由于$y$肯定在$x$被切后若干秒被切,不妨设为$t$秒,则那时四条分出来的小蚯蚓的长度是可以表示的。我们希望能够证明到那时$a_1 > a_2, b_1 > b_2$。我们先来证明$a_1>a_2$,$b$也类似$$a_1 = a_1 + q*t =\left \lfloor px \right \rfloor + q*t$$$$a_2 = \left \lfloor p(y+q*t) \right \rfloor$$则$$a_1-a_2=\left \lfloor px \right \rfloor + q*t-\left \lfloor p(y+q*t) \right \rfloor$$去掉向下取整符号并不会影响答案,因此$$a_1-a_2=p*x+q*t-p*y-p*q*t$$整理得$$a_1-a_2=p(x-y)+q*t(1-p)>0$$故$$a_1>a_2$$

因此我们得出结论:一条蚯蚓如果比另一条蚯蚓早被切,那么它分出来的两条蚯蚓也永远比后分出来的两条蚯蚓要长

于是我们可以考虑维护三个队列$q_1,q_2,q_3$,$q_1$中储存没被切过的蚯蚓,$q_2$中储存切出来的左半条,$q_3$表示右半条。要求队列单调不上升,每一次取出三个队列的队头中的最大值即为所有蚯蚓中最长的,切成两半后分别塞到$q_2,q_3$的队尾。由于刚才证明了后切的一定要短,所以插入队尾后单调性依然满足。故这样的做法是正确的

Code

cur=-INF而不能是-1,因为负数有可能减到很大

/*By DennyQi 2018.8.15*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x << ) + (x << ) + c - '', c = getchar(); return x * w;
}
double p;
int N,M,Q,U,V,T,_mx,pos,tmp,x,y,cur,top;
int q[][MAXN],h[],t[],a[MAXN];
inline bool comp(const int& a, const int& b){ return a>b; }
int main(){
N=r,M=r,Q=r,U=r,V=r,T=r;
p = (double)(U) / (double)(V);
for(int i = ; i <= N; ++i) a[i] = r;
h[] = h[] = h[] = ;
q[][] = q[][] = -INF;
sort(a+,a+N+,comp);
for(int i = ; i <= N; ++i) q[][++t[]] = a[i];
for(int _t = ; _t <= M; ++_t){
cur = -INF;
for(int i = ; i <= ; ++i){
if(h[i] > t[i]) continue;
if(q[i][h[i]] > cur){ cur = q[i][h[i]]; pos = i; }
}
if(_t % T == ) printf("%d ", cur+(_t-)*Q);
++h[pos];
x = (cur+(_t-)*Q) * p, y = (cur+(_t-)*Q) - x;
q[][++t[]] = x-_t*Q, q[][++t[]] = y-_t*Q;
}
puts("");
for(int i = ; i <= ; ++i)
for(int j = h[i]; j <= t[i]; ++j) a[++top] = q[i][j];
sort(a+,a+top+,comp);
for(int i = ; i <= top; ++i)
if(i % T == ) printf("%d ", a[i]+M*Q);
return ;
}

[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. NC16430 [NOIP2016]蚯蚓

    NC16430 [NOIP2016]蚯蚓 题目 题目描述 本题中,我们将用符号 \(\lfloor c \rfloor\) 表示对 c 向下取整,例如:\(\lfloor 3.0 \rfloor = ...

  4. 【bzoj4721】[Noip2016]蚯蚓

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

  5. 【uoj264】 NOIP2016—蚯蚓

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

  6. BZOJ4721 [Noip2016]蚯蚓

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

  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. BZOJ4289 Tax 最短路建模

    给定一个带边权的无向图,求1到n的最小代价路径.经过一个点的代价是路径上这个点的入边和出边的较大权值. \(n \le 100000, m \le 200000\). 一般的建图是考虑每个点,其入边和 ...

  2. A direct formulation for sparse PCA using semidefinite programming

    目录 背景 Sparse eigenvectors(单个向量的稀疏化) 初始问题(low-rank的思想?) 等价问题 最小化\(\lambda\) 得到下列问题(易推) 再来一个等价问题 条件放松( ...

  3. kattis Programming Tutors 给游客与导游匹配(二分+二分图)

    题目来源:https://vjudge.net/problem/Kattis-programmingtutors 题意: 有n个游客,n个导游,给出他们的坐标,问你怎么匹配可以使他们最大距离最小 题解 ...

  4. 使用matplotlib画饼图

    import matplotlib.pyplot as pltx = [4, 9, 21, 55, 30, 18]labels = ['math', 'history', 'chemistry', ' ...

  5. elasticsearch判断索引是否存在

    一.判断索引是否存在 指定索引名,判断指定的索引是否存在集群中 /** * 判断指定的索引名是否存在 * @param indexName 索引名 * @return 存在:true; 不存在:fal ...

  6. TCP粘包问题解析与解决

    一.粘包分析 作者本人在写一个FTP项目时,在文件的上传下载模块遇到了粘包问题.在网上找了一些解决办法,感觉对我情况都不好用,因此自己想了个比较好的解决办法,提供参考 1.1 粘包现象 在客户端与服务 ...

  7. semantic-ui 标题

    在semantic-ui中定义了5中标题样式,注意HTML中有h1-h6,而semantic-ui中只有h1-h5. 不过需要注意的是,semantic-ui的标题仍旧使用h1-h5来表示,但是在cl ...

  8. PHP常见错误汇总

    日常开发和调试的时候,经常会遇到一些错误,光怪陆离的不知所以,所以,特此将错误汇总一下,借鉴!!! 1. 原因分析:  一般可能是该文件出现了问题,检查一下代码和格式,是否出现开始的地方出现了空格,或 ...

  9. 自己用习惯的idea快捷键笔记

    Ctrl + Space 自动完成(win10下冲突不能用,自己换成 Alt + \ ) 切换方法是菜单中依次打开 file -> settings -> keymap,搜索complet ...

  10. zookeeper的安装和启动教程

    zookeeper的安装和启动 zookeeper安装包所在目录: 上传文件到虚拟机.现在本地新建一个目录setup,将zookeeper压缩包复制进去. ALT+P打开一个标签,操作如下put命令. ...