Day1

「JOISC 2017 Day 1」开荒者

首先观察部分分发现分档很多,于是考虑一步步思考上来。

首先有一点关键观察(一):

  • 风吹的顺序是无所谓的,令分别往东、西、南、北吹了 \(r, l, d, u\) 次,那么每个初始有草的位置往北 \(u\) 往南 \(d\) 往东 \(r\) 往西 \(l\) 个单位都会被其草籽覆盖且只有这些位置被覆盖。

那么一个简单的想法是直接枚举 \(r, l, d, u\) 然后求矩形并判定,复杂度 \(\mathcal{O}(r ^ 3c ^ 3)/\mathcal{O}(r ^ 2c ^ 2n \log n)\),然后可以通过简单的优化通过第二个包,这里略过。

观察第三个包,很明显就是在提示我们可以在一个维度用多项式复杂度算法,令一个维度随意,那么基础的想法就是去除掉一个维度的限制。

因此首先考虑只有一个维度怎么做:最左最右的草限定了往左 \(a\) 往右 \(b\) 至少要吹多少次,中间的间距限定了往左右分别要吹多少次 \(c\),那么 \(\max(a + b, c)\) 就是答案。

因此我们考虑只枚举 \(l, r\),那么每行就变为了上面的一维问题,注意到本质不同的行只有区间端点个,因此复杂度 \(\mathcal{O}(c ^ 2n ^ 2)\)(当然为了通过第三个包要改为枚举 \(u, d\) 是类似的)

接下来看起来就要给出一个多项式做法,当值域较大的 稀疏图 而枚举量涉及值域大小的时候,通常考虑减少不必要的枚举,那么就要从枚举 \(l, r\) 上下功夫。

此时我们有如下观察(二):

  • 一定存在一个最优方案使得至少有一株草的左边界或右边界要恰好卡在整个区域的左右边界上。

假设不存在,若 \(l > 0\) 则考虑将 \(l \leftarrow l - 1, r \leftarrow r + 1\) 也就是将所有草的区间向右整体平移一格,那么容易发现此时南北方向上的最优解不变,一定能调整到观察中的情况。

否则一定至少有一株草就在左边界上,矛盾。

那么不妨考虑左边界被卡的情况,右边界同理,此时合法的 \(l\) 取值只有 \(\mathcal{O}(n)\) 种。

此时继续类似地观察(三)有:一定存在一种最优方案使得右边界要么被卡,要么使得至少存在两个区间左右端点恰好相邻。

因此此时的有效右端点数量只有 \(\mathcal{O}(n ^ 2)\) 个,那么总共的左右端点有效数量就为 \(\mathcal{O}(n ^ 3)\) 个,此时我们再去做原先的暴力,复杂度 \(\mathcal{O}(n ^ 5)\).

发现直接暴力的过程太冗杂了,考虑优化上面暴力的计算。

根据观察二的证明,发现在线段整体平移的过程中有很多列的计算是重复的,于是对 \(l + r\) 相同的区间一起考虑。

转换一个思路:将所有线段视作不动,而将整个区域在线段上面移动。

由上面对有效 \(l, r\) 的分析可以看出有效的 \(l + r\) 长度来源于两个部分:

  • 左边界右边界均被卡,这里数量是 \(\mathcal{O}(n ^ 2)\) 的。
  • 左边界被卡,\(r\) 使得存在两个区间左右端点相邻,注意到这里区间长度总是两点之间距离,因此也是 \(\mathcal{O}(n ^ 2)\) 的。

因此我们发现本质不同的 \(l + r\) 至多 \(\mathcal{O}(n ^ 2)\) 种。

那么将所有关键列(区间左端点,右端点后面一个点)提取出来抽象成点,有三个属性 \(a, b, c\) 即一维问题下定义的三个量,那么问题就是求所有长度固定区间的 \(\max a, \max b, \max c\) 直接用单调队列维护即可。

瓶颈在于计算所有 \(l, r\) 的关键列上的属性,根据上面的分析关键列是 \(\mathcal{O}(n)\) 的,复杂度 \(\mathcal{O}(n ^ 4)\).

考虑继续解决这个瓶颈,注意到关键列上的元素不减,那么这本质上就是维护了 \(\mathcal{O}(n)\) 个序列,每个序列支持插入一个元素(插入总次数为 \(\mathcal{O}(n ^ 2)\)),查询每个序列的最大值,最小值,和相邻大小元素差的最大值。

这是一个经典问题,倒序处理上述三个值均有单调性,用链表维护,复杂度 \(\mathcal{O}(n ^ 3)\).

当然最后这个维护部分不是瓶颈,也可以用 set 偷懒。

「JOISC 2017 Day 1」港口设施

首先发现两个相交的区间不能放进同一个栈,因此可以发现一个栈是合法的当且仅当其中的所有区间只有包含或相离关系。

如果我们把相交但不包含的区间之间连边,那么问题就转化为二分图染色问题,考虑优化连边。

首先将每个区间的连边转化成比较好观察的形式:将所有区间按照左端点排序,按照右端点依次考虑连边,每连一个区间就删掉这个区间,那么每次连接的区间都是排序后连续的一段。

我们发现,每次连一段区间的意义是:钦定这段区间内点的颜色全部相同并且与当前点颜色不同,那么之前已经连过的区间一定可以保证颜色相同,所以当前区间和之前区间的交集就可以只连一条边。

那么我们用并查集维护颜色相同的区间,这样每次连接一个区间就只需要连接其分成的若干个颜色不同的连通块就可以了,这样连接的总边数就降低到了线性。

需要注意的是,我们需要支持删点。

观察这里的操作,我们发现并不需要真的把点删掉,可以将已经删去了的点同样加入颜色维护的联通块。

并且我们如果需要向一个 与当前区间交集存在点没被删 的联通块连边,那么连接其中任何一个点都是可以的(包括被删的点)

因此我们还需要再维护一个并查集(或者链表)来跳过当前被删过的点,复杂度 \(\mathcal{O}(n\alpha(n))\).

JOISC 2017的更多相关文章

  1. JOISC 2017 Day1 T3 烟花棒

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

  2. 「JOISC 2017 Day 3」幽深府邸

    题解: 和hnoi2018day2t1基本一样 我想了半小时想出了一个很麻烦的做法 写了之后发现假掉了 刚开始想的是 先预处理出每个门要打开至少要在左边的哪个点$L[]$,右边的哪个点$R[]$ 对每 ...

  3. JOISC 2017 自然公园

    吐槽 YMD的课件是真的毒,YYB的也很毒. 题目链接 LOJ sol 我是一个一个Subtask做的... Subtask 1 \(O(n^2)\)枚举每两个点有没有边即可. Subtask 2 链 ...

  4. loj2395 [JOISC 2017 Day 2]火车旅行

    传送门 分析 我们知道无论往左走还是往右走一定都是往不低于这个点的地方走 于是我们可以考虑用倍增来维护一个点向左和向右走$2^i$最远分别能走到哪里 我们可以先用单调栈求出直走一步的情况,之后再处理倍 ...

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

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

  6. loj#2391 「JOISC 2017 Day 1」港口设施

    分析 https://yhx-12243.github.io/OI-transit/records/uoj356%3Bloj2391%3Bac2534.html 代码 #include<bits ...

  7. WC2019 题目集

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

  8. 退役前的最后的做题记录upd:2019.04.04

    考试考到自闭,每天被吊打. 还有几天可能就要AFO了呢... Luogu3602:Koishi Loves Segments 从左向右,每次删除右端点最大的即可. [HEOI2014]南园满地堆轻絮 ...

  9. ZJOI2019Round#2

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

随机推荐

  1. 【转】GitHub 的 Pull Request 和 GitLab 的 Merge Request 有区别吗?

    在 GitHub 上混久了,经常听到 Pull Request,在 GitLab 上混久了,则经常 提起 Merge Request ,然而它们之间有不同吗?为什么要用两个不同的名称? 要追溯这两个名 ...

  2. CS5210设计HDMI to VGA方案|CS5210资料|CS5210设计电路方案

    CS5210是一款HDMI转VGA转换器方案,其输出VGA信号可送到CRT/LED显示器,及投影机等,输入HDMI信号可以驳接电脑.PS3,XBOX360.蓝光DVD,输出VGA可以CRT/LED显示 ...

  3. Oracle中的基本数据类型

    一.Oracle 基本数据类型 1.字符数据类型 CHAR:存储固定长度的字符串,如果没有指定长度,默认为1个字节,如果数据长度没有达到指定的长度,则通过填充空格的方式来使其达到定义的长度(CHAR类 ...

  4. emqx启用redis认证插件

    本次测试使用的是免费版的 emqx-windows-4.3.10 版本 1.修改redis插件 emqx_auth_redis.conf  设置用户名密码,    auth.redis.passwor ...

  5. Hangfire任务调度框架使用

    1.HangFire简介 HangFire是一个免费简单实用的分布式后台定时调度服务,在现在.net开发中,人气算是很高的. HangFire提供了内置集成化的控制台,可以直观明了的查看作业调度情况, ...

  6. RabbitMQ基础教程系列

    Ubuntu16.04下,erlang安装和rabbitmq安装步骤 Ubuntu16.04下,rabbimq集群搭建 C# .net 环境下使用rabbitmq消息队列 .net core使用rab ...

  7. 2021 编程语言排行榜出炉!C#年度语言奖

    IEEE Spectrum 发布了 2021 年度编程语言排行榜,其中 Python 在总榜单以及其他几个分榜单中依然牢牢占据第一名的位置.另外值得关注的是微软 C# 语言,它的排行从 2020 年的 ...

  8. Pytest_简介与安装(1)

    一.Pytest简介 pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但更灵活.官方网站优点简介: 非常容易上手,入门简单,文档丰富,文档中有很多实例可 ...

  9. HTTP 408 问题 - Koa body parser

    环境描述: 1.nodejs 作为 api 服务器,转发请求给 nginx 2.用 curl 测试,返回 408 找了很久没有找到原因,发现了一篇文章: https://lujunda.cn/2016 ...

  10. Go语言系列之依赖管理

    依赖管理 为什么需要依赖管理? 最早的时候,Go所依赖的所有的第三方库都放在GOPATH这个目录下面.这就导致了同一个库只能保存一个版本的代码.如果不同的项目依赖同一个第三方的库的不同版本,应该怎么解 ...