[loj2392]烟花棒
显然,有以下三个性质(思路):
1.烟花传递总是在烟花将要燃尽时将烟花恰传给另一个人
2.烟花不燃烧的人总是向烟花正在燃烧的人靠拢,并且重合后会一直跟着(燃尽时替上)
3.烟花正在燃烧的人总是向下一个"跟着"的人靠拢(等着不如接上后返回)
此时,过程完全由"跟着"的顺序决定(思考一下如何决定?),也即以$k$为中心向两侧扩展
再考虑相对位置,不难发现扩展$x$时,其与烟花正在燃烧的人的距离总是$\begin{cases}a_{x+1}-a_{x}&(x<k)\\a_{x}-a_{x-1}&(x>k)\end{cases}$(与另一侧扩展的人和扩展的顺序均无关),具体可以归纳证明
二分枚举答案$v$,并维护当前烟花剩余可燃烧时间$t$(初始为$k$),问题即变为:
有两个队列(依次存储两侧拓展的距离),每次任选一个队列,记其顶部元素为$d$,若$t\ge \frac{d}{2v}$则可以将$t$变为$t-\frac{d}{2v}+k$并删除该顶部元素,判断是否存在一种删除顺序可以删光两个队列
从两个队列中取出最短的非空前缀满足$\sum (k-\frac{d}{2v})\ge 0$,若可以取该前缀(即要求$t\ge lim$,$lim$可以求出)显然总可以直接取掉,重复此过程(直至均不存在这样的前缀或均无法取)
若是因后者而结束,显然问题即无解
若是因前者而结束,即此时两个队列中任意非空前缀和均小于0,不妨先得到最终的$t$并考虑逆过程(即过程中的$k$和$\frac{d}{2v}$交换一下、队列翻转一下),仍可以使用上述贪心
此时的后缀和即是原来的前缀和取相反数,总大于等于0,也即不会出现"不存在这样的前缀"的情况
由此,单次判定复杂度为$o(n)$,总复杂度为$o(n\log n)$,可以通过

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 100005
4 #define ll long long
5 #define fi first
6 #define se second
7 int n,t,k,x[N];
8 vector<int>vl,vr;
9 vector<pair<ll,ll> >Vl,Vr;
10 bool check(int v){
11 vl.clear(),vr.clear(),Vl.clear(),Vr.clear();
12 for(int i=k;i>1;i--)vl.push_back(x[i]-x[i-1]);
13 for(int i=k+1;i<=n;i++)vr.push_back(x[i]-x[i-1]);
14
15 int lst=-1;
16 ll lim=0,sum=0;
17 for(int i=0;i<vl.size();i++){
18 lim=max(lim,vl[i]-sum),sum+=v-vl[i];
19 if (sum>=0){
20 Vl.push_back(make_pair(lim,sum));
21 lim=sum=0,lst=i;
22 }
23 }
24 reverse(vl.begin(),vl.end());
25 for(int i=0;i<=lst;i++)vl.pop_back();
26
27 lst=-1,lim=sum=0;
28 for(int i=0;i<vr.size();i++){
29 lim=max(lim,vr[i]-sum),sum+=v-vr[i];
30 if (sum>=0){
31 Vr.push_back(make_pair(lim,sum));
32 lim=sum=0,lst=i;
33 }
34 }
35 reverse(vr.begin(),vr.end());
36 for(int i=0;i<=lst;i++)vr.pop_back();
37
38 ll ans=v;
39 for(int i=0,j=0;(i<Vl.size())||(j<Vr.size());)
40 if ((i<Vl.size())&&(Vl[i].fi<=ans))ans+=Vl[i++].se;
41 else{
42 if ((j<Vr.size())&&(Vr[j].fi<=ans))ans+=Vr[j++].se;
43 else return 0;
44 }
45 for(int i=0;i<vl.size();i++)ans+=v-vl[i];
46 for(int i=0;i<vr.size();i++)ans+=v-vr[i];
47 if (ans<0)return 0;
48
49 Vl.clear(),Vr.clear();
50 lst=-1,lim=sum=0;
51 for(int i=0;i<vl.size();i++){
52 lim=max(lim,v-sum),sum+=vl[i]-v;
53 if (sum>=0){
54 Vl.push_back(make_pair(lim,sum));
55 lim=sum=0,lst=i;
56 }
57 }
58
59 lst=-1,lim=sum=0;
60 for(int i=0;i<vr.size();i++){
61 lim=max(lim,v-sum),sum+=vr[i]-v;
62 if (sum>=0){
63 Vr.push_back(make_pair(lim,sum));
64 lim=sum=0,lst=i;
65 }
66 }
67
68 for(int i=0,j=0;(i<Vl.size())||(j<Vr.size());)
69 if ((i<Vl.size())&&(Vl[i].fi<=ans))ans+=Vl[i++].se;
70 else{
71 if ((j<Vr.size())&&(Vr[j].fi<=ans))ans+=Vr[j++].se;
72 else return 0;
73 }
74 return 1;
75 }
76 int main(){
77 scanf("%d%d%d",&n,&k,&t),t<<=1;
78 for(int i=1;i<=n;i++)scanf("%d",&x[i]);
79 if (x[n]==0){
80 printf("0\n");
81 return 0;
82 }
83 int l=0,r=(x[n]-1)/t+1;
84 while (l<r){
85 int mid=(l+r>>1);
86 if (check(mid*t))r=mid;
87 else l=mid+1;
88 }
89 printf("%d\n",l);
90 return 0;
91 }
[loj2392]烟花棒的更多相关文章
- JOISC 2017 Day1 T3 烟花棒
JOISC 2017 Day1 T3 烟花棒 题意: 数轴上有\(N\)人在放烟花,一开始只有第\(K\)个人的烟花是点燃的,烟花燃烧的时间为\(T\)秒,求让所有人的烟花都可以点燃的速度的最小值 ...
- LOJ2392 JOISC2017 烟花棒 二分、贪心
传送门 先二分一个最大速度\(v\). 分析移动的性质.很显然的事情是在火焰两边的所有人都会往火焰的方向以最快的速度运动,这样可以使当前位置更早获得火焰,同时当前拥有火焰的若干个人为了传递火焰自然也会 ...
- loj 2392「JOISC 2017 Day 1」烟花棒
loj 答案显然满足二分性,先二分一个速度\(v\) 然后显然所有没有点火的都会往中间点火的人方向走,并且如果两个人相遇不会马上点火,要等到火快熄灭的时候才点火,所以这两个人之后应该在一起行动.另外有 ...
- WC2019 题目集
最近写的一些 WC2019 上讲的一些题.还是怕忘了,写点东西记录一下. LOJ2983 「WC2019」数树 题意 本题包含三个问题: 问题 0:已知两棵 \(n\) 个节点的树的形态(两棵树的节点 ...
- ZJOI2019Round#2
乱听课记录 关于树的分治问题&杂题选讲 张哲宇 边分治 (边分不是很鸡肋吗) 例题一 题目大意:给出两颗有正负边权的树,求出两个点\(u,v\)使得两棵树中\((u,v)\)距离的和最大. ...
- 过年有燃放烟花爆竹禁令那我们用css写一个仙女棒烟花看看吧
先是去找了一张简易画的烟花照片,可以看出主要结构为歪曲的线条结构. 方案一: 弯曲的线条第一反应到的就是"圆角边框": width: 200px; height: 200px; b ...
- cocos2d-x游戏开发之烟花粒子效果
//散烟花及“太”“棒”“了”效果 void mygame::playfire() { sprite *tai = sprite::create("tai.png"); tai-& ...
- 8个超棒的HTML5网站设计欣赏
我们听到了很多关于HTML5的新闻和技术动向,一个又一个的新的东西不停的出现,那么最近HTML5的技术应用又如何呢?HTML5又和CSS及其Javascript如何一起改变我们的网站设计和实现的呢? ...
- 基于2D-RNN的鲁棒行人跟踪
基于2D-RNN的鲁棒行人跟踪 Recurrent Neural Networks RNN 行人跟踪 读"G.L. Masala, et.al., 2D Recurrent Neural N ...
随机推荐
- FastAPI(64)- Settings and Environment Variables 配置项和环境变量
背景 在许多情况下,应用程序可能需要一些外部设置或配置,例如密钥.数据库凭据.电子邮件服务凭据等. 大多数这些设置都是可变的(可以更改),例如数据库 URL,很多可能是敏感数据,比如密码 出于这个原因 ...
- java 从零开始手写 RPC (07)-timeout 超时处理
<过时不候> 最漫长的莫过于等待 我们不可能永远等一个人 就像请求 永远等待响应 超时处理 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RP ...
- 调试器地址出现大小端紊乱,引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。
今天在编写一系列新增需求代码后,开始调试代码 发现上个版本正常可运行的代码出现了:引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突. 上个版本数代码 ...
- noip模拟78
考试过程:先读题,然后觉得开题顺序1 4 2 3. 首先是T1,要是不考虑重复这题很简单,但是考虑重复就比较复杂了,我打完,对拍完差不多用了两个小时,然后就是忘了算内存,结果内存爆了,\(100pts ...
- 一文读懂Android进程及TCP动态心跳保活
一直以来,APP进程保活都是 各软件提供商 和 个人开发者 头疼的问题.毕竟一切的商业模式都建立在用户对APP的使用上,因此保证APP进程的唤醒,提升用户的使用时间,便是软件提供商和个人开发者的永恒追 ...
- 零基础如何更好的学习Linux
本节旨在介绍对于初学者如何学习 Linux 的建议.如果你已经确定对 Linux 产生了兴趣,那么接下来我们介绍一下学习 Linux 的方法. 如何去学习 学习大多类似庖丁解牛,对事物的认识一般都是由 ...
- STM32入门-STM32时钟系统,时钟初始化配置函数
在前面推文的介绍中,我们知道STM32系统复位后首先进入SystemInit函数进行时钟的设置,然后进入主函数main.那么我们就来看下SystemInit()函数到底做了哪些操作,首先打开我们前面使 ...
- lollipop_softap启动wifi ap失败
最近一直在调试lollipop,翻译成中文好像是棒棒糖的意思,就是个wifi控制管理工具,比如设置DLNA或者WFD模式等,其原理是通过本地通信工具sockets控制其他接口来启动wpa_suplic ...
- 有向路径检查 牛客网 程序员面试金典 C++ Python
有向路径检查 牛客网 程序员面试金典 C++ Python 题目描述 对于一个有向图,请实现一个算法,找出两点之间是否存在一条路径. 给定图中的两个结点的指针DirectedGraphNode* a, ...
- cf13B Letter A(分类+简单计算几何,,)
题意: 给三个线段(每个线段的两个端点的坐标),问这三个线段能否组成字母A. 组成字母A的条件: 1.两个线段有公共端点. 2.这两个线段夹角小于等于90度. 3.第三个线段的两个端点分别在这两个线段 ...