显然,有以下三个性质(思路):

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]烟花棒的更多相关文章

  1. JOISC 2017 Day1 T3 烟花棒

    JOISC 2017 Day1 T3 烟花棒 题意: ​ 数轴上有\(N\)人在放烟花,一开始只有第\(K\)个人的烟花是点燃的,烟花燃烧的时间为\(T\)秒,求让所有人的烟花都可以点燃的速度的最小值 ...

  2. LOJ2392 JOISC2017 烟花棒 二分、贪心

    传送门 先二分一个最大速度\(v\). 分析移动的性质.很显然的事情是在火焰两边的所有人都会往火焰的方向以最快的速度运动,这样可以使当前位置更早获得火焰,同时当前拥有火焰的若干个人为了传递火焰自然也会 ...

  3. loj 2392「JOISC 2017 Day 1」烟花棒

    loj 答案显然满足二分性,先二分一个速度\(v\) 然后显然所有没有点火的都会往中间点火的人方向走,并且如果两个人相遇不会马上点火,要等到火快熄灭的时候才点火,所以这两个人之后应该在一起行动.另外有 ...

  4. WC2019 题目集

    最近写的一些 WC2019 上讲的一些题.还是怕忘了,写点东西记录一下. LOJ2983 「WC2019」数树 题意 本题包含三个问题: 问题 0:已知两棵 \(n\) 个节点的树的形态(两棵树的节点 ...

  5. ZJOI2019Round#2

    乱听课记录 关于树的分治问题&杂题选讲 张哲宇 边分治 (边分不是很鸡肋吗) 例题一 题目大意:给出两颗有正负边权的树,求出两个点\(u,v​\)使得两棵树中\((u,v)​\)距离的和最大. ...

  6. 过年有燃放烟花爆竹禁令那我们用css写一个仙女棒烟花看看吧

    先是去找了一张简易画的烟花照片,可以看出主要结构为歪曲的线条结构. 方案一: 弯曲的线条第一反应到的就是"圆角边框": width: 200px; height: 200px; b ...

  7. cocos2d-x游戏开发之烟花粒子效果

    //散烟花及“太”“棒”“了”效果 void mygame::playfire() { sprite *tai = sprite::create("tai.png"); tai-& ...

  8. 8个超棒的HTML5网站设计欣赏

    我们听到了很多关于HTML5的新闻和技术动向,一个又一个的新的东西不停的出现,那么最近HTML5的技术应用又如何呢?HTML5又和CSS及其Javascript如何一起改变我们的网站设计和实现的呢? ...

  9. 基于2D-RNN的鲁棒行人跟踪

    基于2D-RNN的鲁棒行人跟踪 Recurrent Neural Networks RNN 行人跟踪 读"G.L. Masala, et.al., 2D Recurrent Neural N ...

随机推荐

  1. ECMA 2022 (es13) 新特性

    本文主要整理了截至到 2021年10月12日 为止的且处于 Stage 3->Stage 4 阶段的ECMA提案. 主要包括: Class Fields RegExp Match Indices ...

  2. 题解 [POI2013]SPA-Walk

    题目传送门 题目大意 给出两个长度为 \(n\) 的 \(01\) 串,问是否可以通过某一位把 \(s\) 变为 \(t\),但是中途不能变为 \(k\) 个 \(01\) 串中任意一个,问是否可行. ...

  3. CF850E Random Elections 题解

    题目传送门 题目大意 没法描述,过于繁杂. 思路 果然自己是个菜鸡,只能靠读题解读题,难受极了,其实不是很难自己应该做得出来的....哎.... 不难发现可以统计 \(A\) 获胜的情况乘上 \(3\ ...

  4. Java(45)JDK新特性之String流

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201671.html 博客主页:https://www.cnblogs.com/testero ...

  5. PromQL的简单使用

    PromQL的简单使用 一.背景 二.PromQL的数据类型 三.字面量 1.字符串字面量 2.浮点数字面量 四.时间序列选择器 1.即时向量选择器 1.组成部分 2.指标名称和匹配器的组合 3.匹配 ...

  6. mybatis自定义分页拦截器

    最近看了一下项目中代码,发现系统中使用的mybatis分页使用的是mybatis自带的分页,即使用RowBounds来进行分页,而这种分页是基于内存分页,即一次查出所有的数据,然后再返回分页需要的数据 ...

  7. Oracle创建表、删除表、修改表、字段增删改 语句总结

    创建表: create table 表名 ( 字段名1 字段类型 默认值 是否为空 , 字段名2 字段类型 默认值 是否为空, 字段名3 字段类型 默认值 是否为空, ...... ); 创建一个us ...

  8. 理解前端blob和ArrayBuffer,前端接受文件损坏的问题

    1 downloadTemplate().then(res =>{ 2 3 const data = res.data 4 const url = window.URL.createObject ...

  9. Go websocket EOF bug

    背景 使用的 golang.org/x/net/websocket 包,前端一发来消息就报错 if err = websocket.Message.Receive(ws, &msg); err ...

  10. 02-Java中的锁详解

    I. 使用Lock接口 只要不涉及到复杂用法,一般采用的是Java的synchronized机制 不过,Lock可以提供一些synchronized不支持的机制 非阻塞的获取锁:尝试获取锁,如果能获取 ...