[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 ...
随机推荐
- TypeScript 枚举指南
枚举是受 TypeScript 支持的数据类型.枚举允许您定义一组命名常量.使用它们可以更轻松地记录意图或创建一组不同的案例.枚举大多数用于面向对象的编程语言(如 Java 和 C#)中,现在也可以 ...
- 利用PATH环境变量 - 提升linux权限~👻
利用PATH提升linux权限 参考地址:https://www.hackingarticles.in/linux-privilege-escalation-using-path-variable/ ...
- CVPR2021提出的一些新数据集汇总
前言 在<论文创新的常见思路总结>(点击标题阅读)一文中,提到过一些新的数据集或者新方向比较容易出论文.因此纠结于选择课题方向的读者可以考虑以下几个新方向.文末附相关论文获取方式. ...
- JavaScript兼容性汇总
一般兼容性问都体现到DOM和事件上 只聊ie6+版本浏览器,希望小伙伴们别纠结更低版本浏览器哈^_^ DOM 获取元素 document.getElementsByclassName 不兼容ie6 ...
- 3 Implementation: The Big Picture 实现:蓝图
三.Implementation: The Big Picture 实现:蓝图 3.1 Layering of a .NET Solution .Net解决方案的分层 The picture belo ...
- JavaCPP快速入门(官方demo增强版)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Canal的简单使用
Canal的简单实用 一.背景 二.canal的工作原理 三.安装canal 1.mysql配置相关 1.检测binlog是否开启 2.mysql开启binlog 3.创建canal用户 2.cana ...
- elf文件--基于《ctf竞赛权威指南pwn篇》
1.ELF概念: ELF(Executable and Linkable Format),即"可执行可链接格式",最初由UNIX系统实验室作为应用程序二进制接口(Applicati ...
- C语言零基础入门难发愁,那就快来看看这篇基础整理资料吧
C语言程序的结构认识 用一个简单的c程序例子,介绍c语言的基本构成.格式.以及良好的书写风格,使小伙伴对c语言有个初步认识. 例1:计算两个整数之和的c程序: #include main() { in ...
- 用C++实现的数独解题程序 SudokuSolver 2.6 的新功能及相关分析
SudokuSolver 2.6 的新功能及相关分析 SudokuSolver 2.6 的命令清单如下: H:\Read\num\Release>sudoku.exe Order please: ...