[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 ...
随机推荐
- ES6箭头函数(箭头函数和普通函数的区别)
箭头函数 一个参数 // 只有一个参数 // f : 函数名称 // v : 函数参数 // v+v : 函数内容 let f=v=> v+v console.log(f(10)) //20 两 ...
- 从零入门 Serverless | Serverless 应用如何管理日志 & 持久化数据
作者 | 竞霄 阿里巴巴开发工程师 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 Se ...
- css3新增属性-background背景
css3新增属性 边框属性 背景属性 文字属性 颜色属性 背景属性 属性 说明 background-image 添加背景图片 background-size 指定背景图像的大小 background ...
- OSI模型与TCP/IP模型
OSI模型与TCP/IP模型 OSI参考模型: ---开放式系统互联参考模型 OSI/RM ISO ---国际标准化组织 --1979 应用层 ---- 通过应用进程间的交互来完成特定网络应用 表 ...
- .Net Core微信服务商二次进件
最近商城进行微信服务商二次进件的开发,大致有几个点 一,服务商签名 二,服务商证书获取 三,图片上传 四,敏感信息加密 五,查询进件状态 除此之外,就是进件信息的拼装 电商二级商户进件申请单-状态流转 ...
- Kafka消息(存储)格式及索引组织方式
要深入学习Kafka,理解Kafka的存储机制是非常重要的.本文介绍Kafka存储消息的格式以及数据文件和索引组织方式,以便更好的理解Kafka是如何工作的. Kafka消息存储格式 Kafka为了保 ...
- Codeforces Round #747 (Div. 2) Editorial
Codeforces Round #747 (Div. 2) A. Consecutive Sum Riddle 思路分析: 一开始想起了那个公式\(l + (l + 1) + - + (r − 1) ...
- BUAA 软工 | 从计算机技术中探索艺术之路
项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 第一次作业-热身! 我在这个课程的目标是 掌握软件开发方法学和工程学知识 这个作业在哪个具体方面帮 ...
- Noip模拟81 2021.10.20
T1 语言 比较简单的题,然后就瞎写了,所以考场上就我一个写了线段树的,所以我的常数.... 所以就枚举动词的位置,找前面后面有没有出现$4$即可 1 #include<bits/stdc++. ...
- 洛谷 P5657 [CSP-S2019] 格雷码
链接: P5657 分析: 签到题,不过也有不少细节. 数据范围需要开 unsigned long long ,前年也有很多人因此丢了5分. pow 会出现神必错误,需要手写一个 mpow 函数. 算 ...