[HNOI 2018]转盘
Description
在一个环上有 \(n\) 个物品,第 \(i\) 个物品的出现时间为 \(T_i\) 。一开始你可以任意选择一个物品的位置作为起始位置,然后以这个位置为起点沿正方向走,走一个单位花一个单位的时间,不能调头,可以停留。问至少多少时间可以取完所有的物品。一个物品 \(i\) 能被取当且仅当到达该物品的位置时时间 \(\geq T_i\) ,初始时间为 \(0\) 。支持 \(m\) 次单点修改,强制在线。
\(3\leq n\leq 10^5,0\leq m\leq 10^5\)
Solution
推推性质,容易得到这样的一个结论:不会走到相同的地方两次。换句话说就是相当于选定起点之后,每走到一个位置一定会等到该位置的物品出现取上该物品后再继续走。
感性证明下:考虑为什么会有不符合上述情况的走法,显然是一个离我较远的物品比离我较近的物品先出现,并且早的多,那么我就需要先去取较远的物品再走一圈回来取这个出现时间较晚的物品。不过这样的话,我可以直接把起点放在那个较远的物品处,显然答案不会比我这样走的答案差。
既然有这样的结论,我们先将数组倍长,可以枚举起点,再在起点向右枚举 \(n\) 个,统计一下最大值,最后取个最小值即可。不过这样单次操作就是 \(O(n^2)\) 的,肯定过不了...
考虑到答案就是求:
\[\min_{1\leq i\leq n}\left\{\max_{i\leq j\leq i+n-1}\left\{T_j+(n-1-(j-i))\right\}\right\}\]
其实这个是和式子
\[\min_{1\leq i\leq n}\left\{\max_{i\leq j\leq 2n}\left\{T_j+(n-1-(j-i))\right\}\right\}\]
是等价的。
将式子变一下形,记 \(a_i=T_i-i\)
\[\min_{1\leq i\leq n}\left\{\max_{i\leq j\leq 2n}\left\{a_j\right\}+i\right\}+n-1\]
考虑如何维护这个东西。
我们让线段树每个节点 \(o\) (控制区间为 \([l,r]\) )维护两个值 \(maxn_o\) 和 \(val_o\) 。表示区间 \(a_i\) 最值和 \(\min\limits_{l\leq i\leq mid}\left\{\max\limits_{i\leq j\leq r}\left\{a_j\right\}+i\right\}\) 。
考虑如何维护这个 \(val_o\) 。
对于每个线段树中的非叶子节点,我们需要合并左右儿子的信息。主要的就是考虑右儿子的值会对左儿子中的起点产生影响。
我们不妨记当前节点的右儿子的 \(maxn\) 为 \(mx\) 。
对于左儿子 \(ls\) ,如果他的右儿子的 \(maxn\geq mx\) ,显然 \(ls\) 的左儿子的 \(val\) 值可以直接用;右儿子无法确定,递归处理右儿子。
如果 \(ls\) 的右儿子的 \(maxn\leq mx\) ,显然 \(ls\) 的右儿子的内起点的最小值一定是 \(mid+1+mx\) ;左儿子无法确定,递归处理左儿子。
显然对于每次更新需要 \(\log\) 的递归询问。
至于更新,只要更新线段树一条链上的所有节点。线段树维护的总复杂度为 \(O(n\log_2^2 n)\) 。
Code
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+5;
int n, m, p, t[N], a[N], x, y, last;
struct Segment_tree {
#define lr(o) (o<<1)
#define rr(o) (o<<1|1)
int maxn[N<<2], val[N<<2];
int query(int o, int l, int r, int mx) {
if (l == r) return l+max(mx, maxn[o]); int mid = (l+r)>>1;
if (mx <= maxn[rr(o)]) return min(val[o], query(rr(o), mid+1, r, mx));
else return min(mid+mx+1, query(lr(o), l, mid, mx));
}
void pushup(int o, int l, int mid, int r) {
val[o] = query(lr(o), l, mid, maxn[rr(o)]);
maxn[o] = max(maxn[lr(o)], maxn[rr(o)]);
}
void build(int o, int l, int r) {
if (l == r) {maxn[o] = a[l], val[o] = l+a[l]; return; }
int mid = (l+r)>>1;
build(lr(o), l, mid), build(rr(o), mid+1, r);
pushup(o, l, mid, r);
}
void update(int o, int l, int r, int loc) {
if (l == r) {maxn[o] = a[l], val[o] = l+a[l]; return; }
int mid = (l+r)>>1;
if (loc <= mid) update(lr(o), l, mid, loc);
else update(rr(o), mid+1, r, loc);
pushup(o, l, mid, r);
}
}T;
void work() {
scanf("%d%d%d", &n, &m, &p);
for (int i = 1; i <= n; i++)
scanf("%d", &t[i]), a[i] = t[i]-i, a[i+n] = t[i]-n-i;
T.build(1, 1, n<<1);
printf("%d\n", last = T.val[1]+n-1);
while (m--) {
scanf("%d%d", &x, &y); x ^= last*p, y ^= last*p;
t[x] = y, a[x] = t[x]-x, a[x+n] = t[x]-n-x;
T.update(1, 1, n<<1, x), T.update(1, 1, n<<1, x+n);
printf("%d\n", last = T.val[1]+n-1);
}
}
int main() {work(); return 0; }
[HNOI 2018]转盘的更多相关文章
- [HNOI/AHOI2018]转盘(线段树优化单调)
gugu bz lei了lei了,事独流体毒瘤题 一句话题意:任选一个点开始,每个时刻向前走一步或者站着不动 问实现每一个点都在$T_i$之后被访问到的最短时间 Step 1 该题可证: 最优方案必 ...
- 【HNOI 2018】转盘
Problem Description 一次小 \(G\) 和小 \(H\) 原本准备去聚餐,但由于太麻烦了于是题面简化如下: 一个转盘上有摆成一圈的 \(n\) 个物品(编号 \(1\) 至 \(n ...
- HNOI 2018 简要题解
寻宝游戏 毒瘤题. 估计考试只会前30pts30pts30pts暴力然后果断走人. 正解是考虑到一个数&1\&1&1和∣0|0∣0都没有变化,&0\&0& ...
- [HNOI 2018]道路
Description 题库链接 给出一棵含有 \(n\) 个叶子节点的二叉树,对于每个非叶子节点的节点,其与左儿子相连的边为公路,其与右儿子相连的边为铁路.对于每个节点,选择一条与其儿子相连的铁路或 ...
- [HNOI 2018]游戏
Description 题库链接 有 \(n\) 个房间排成一列,编号为 \(1,2,...,n\) ,相邻的房间之间都有一道门.其中 \(m\) 个门上锁,其余的门都能直接打开.现在已知每把锁的钥匙 ...
- [HNOI 2018]排列
Description 题库链接 给定 \(n\) 个整数 \(a_1, a_2, \dots, a_n, 0 \le ai \le n\) ,以及 \(n\) 个整数 \(w_1, w_2, \do ...
- 【HNOI 2018】毒瘤
Problem Description 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(例如给一个区间内的数同时加上 \(c ...
- 【HNOI 2018】排列
Problem Description 给定 \(n\) 个整数 \(a_1, a_2, \ldots , a_n(0 \le a_i \le n)\),以及 \(n\) 个整数 \(w_1, w_2 ...
- 【HNOI 2018】游戏
Problem Description 一次小 \(G\) 和小 \(H\) 在玩寻宝游戏,有 \(n\) 个房间排成一列,编号为 \(1,2,-,n\),相邻房间之间都有 \(1\) 道门.其中一部 ...
随机推荐
- FP-Growth in Spark MLLib
并行FP-Growth算法思路 上图的单线程形成的FP-Tree. 分布式算法事实上是对FP-Tree进行分割,分而治之 首先,假设我们只关心...|c这个conditional transactio ...
- WPF 改变Datagrid的选中行的颜色
主要通过设置DataGrid的RowStyle和CellStyle即可. <Style TargetType="DataGridRow" x:Key="gridRo ...
- sqlServer数据库纵横表相互转化
sqlServer 数据库纵横表相互转化 一.纵表转横表: 1.纵表: 2.横表: 3. 代码: select Name as '姓名', end) as '语文', end) as '数学', e ...
- MyCat - 背景篇(1)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. SQL与NoSQL 目前,对于互联网海量数据的存储以及处理,按使用场景,分为OLTP(联机事务处理,比如即时 ...
- 201621123023《Java程序设计》第5周学习总结
一.本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 接口.interface.comparable.comparator 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一 ...
- Spring Boot快速搭建Web工程
先想一下,正常我们想要创建一个web服务,首先需要下载tomcat,创建web工程,配置各种web.xml,引入spring的配置,各种配置文件一顿倒腾.....下载有了spring boot,你创建 ...
- poj2506 Tiling
http://poj.org/problem?id=2506 题目大意:用多少种方法可以用2*1或2*2瓦片来铺一个2*n的矩形? 这是一个2*17长方形的样品. 输入是一行行的序列,每一行包含一个整 ...
- mysql enterprise backup入门使用
**************************************************************--1.全备******************************** ...
- 【xsy1018】 小A的字母游戏 扩展CRT
题目大意:有$n$个无限长的循环字符串,所谓循环字符串,就是由某一个子串重复叠加而成.现在想知道最早在哪一位,这n个字符串的那一位的字母相同. 数据范围:$n≤30000$,答案$<2^{63} ...
- Hadoop2.0.0+CDH4.5.0集群配置
Hadoop 2.0.0-cdh4.5.0安装:http://blog.csdn.net/u010967382/article/details/18402217 CDH版本下载:http://arch ...