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

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. 10.11 HTTPS

    没有HTTPS的抓包截图 HTTPS=HTTP + TLS/SSL https 实现过程如下 1.客户端发起HTTPS请求 rewrite www.baidu.com https://www.baid ...

  2. 缓冲区溢出利用与ShellCode编写

    一.实验目的 熟悉编写shellCode的流程 掌握缓冲区溢出的利用 二.实验环境 系统环境:Windows环境 软件环境:C++ ,缓冲区溢出文件链接 三.实验原理 要实施一次有效的缓冲区溢出攻击, ...

  3. 如何用redis统计海量UV?

    前言 我们先思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现? 统计uv的常用方法以及优缺点 其 ...

  4. Dapr + .NET Core实战(十三)跨语言开发

    因为基于Dapr的服务架构是不限语言的,我们来看看Dapr的跨语言开发.我们使用golang,python,.NET来实现跨语言的服务调用,拓扑如下 我们继续使用.NET 5的fontend和back ...

  5. Serverless 在编程教育中的实践

    说起Serverless这个词,我想大家应该都不陌生,那么Serverless这个词到底是什么意思?Serverless到底能解决什么问题?可能很多朋友还没有深刻的体会和体感,这篇文章我就和大家一起聊 ...

  6. 题解 [HAOI2017]方案数

    题目传送门 Solution 我们没有障碍的时候很好做,直接设 \(f_{i,j,k}\) 表示到 \((x,y,z)\) \(x\) 有 \(i\) 位为 \(1\),\(y\) 有 \(j\) 位 ...

  7. Centos7 python3环境搭建 兼容python2.7

    Centos7 python3环境搭建 兼容python2.7 安装前提依赖 yum install openssl-devel bzip2-devel expat-devel gdbm-devel ...

  8. ToString()字符串转换你用正确了吗?

    前言 在开发中,ToString()这个方法太方便了,以致于误解大家转换时都是直接Object.ToString()直接转换, 其实不然, 一般都是转之前先判断是否为null后再进行转换,否则会直接报 ...

  9. 【数据结构与算法Python版学习笔记】图——最短路径问题、最小生成树

    最短路径问题 概念 可以通过"traceroute"命令来跟踪信息传送的路径: traceroute www.lib.pku.edu.cn 可以将互联网路由器体系表示为一个带权边的 ...

  10. 防止SQL注入总结

    1.预编译(占位符)可以很大程度上防止SQL注入 预编译的原理是数据库厂商提供的JAR包中,对参数进行了转义 2.mybatis中,能用# 的地方,不用$,因为#是预编译占位符形式,可以防止SQL注入 ...