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]转盘的更多相关文章

  1. [HNOI/AHOI2018]转盘(线段树优化单调)

    gugu  bz lei了lei了,事独流体毒瘤题 一句话题意:任选一个点开始,每个时刻向前走一步或者站着不动 问实现每一个点都在$T_i$之后被访问到的最短时间 Step 1 该题可证: 最优方案必 ...

  2. 【HNOI 2018】转盘

    Problem Description 一次小 \(G\) 和小 \(H\) 原本准备去聚餐,但由于太麻烦了于是题面简化如下: 一个转盘上有摆成一圈的 \(n\) 个物品(编号 \(1\) 至 \(n ...

  3. HNOI 2018 简要题解

    寻宝游戏 毒瘤题. 估计考试只会前30pts30pts30pts暴力然后果断走人. 正解是考虑到一个数&1\&1&1和∣0|0∣0都没有变化,&0\&0& ...

  4. [HNOI 2018]道路

    Description 题库链接 给出一棵含有 \(n\) 个叶子节点的二叉树,对于每个非叶子节点的节点,其与左儿子相连的边为公路,其与右儿子相连的边为铁路.对于每个节点,选择一条与其儿子相连的铁路或 ...

  5. [HNOI 2018]游戏

    Description 题库链接 有 \(n\) 个房间排成一列,编号为 \(1,2,...,n\) ,相邻的房间之间都有一道门.其中 \(m\) 个门上锁,其余的门都能直接打开.现在已知每把锁的钥匙 ...

  6. [HNOI 2018]排列

    Description 题库链接 给定 \(n\) 个整数 \(a_1, a_2, \dots, a_n, 0 \le ai \le n\) ,以及 \(n\) 个整数 \(w_1, w_2, \do ...

  7. 【HNOI 2018】毒瘤

    Problem Description 从前有一名毒瘤. 毒瘤最近发现了量产毒瘤题的奥秘.考虑如下类型的数据结构题:给出一个数组,要求支持若干种奇奇怪怪的修改操作(例如给一个区间内的数同时加上 \(c ...

  8. 【HNOI 2018】排列

    Problem Description 给定 \(n\) 个整数 \(a_1, a_2, \ldots , a_n(0 \le a_i \le n)\),以及 \(n\) 个整数 \(w_1, w_2 ...

  9. 【HNOI 2018】游戏

    Problem Description 一次小 \(G\) 和小 \(H\) 在玩寻宝游戏,有 \(n\) 个房间排成一列,编号为 \(1,2,-,n\),相邻房间之间都有 \(1\) 道门.其中一部 ...

随机推荐

  1. ADO.NET系列之Command对象

    ADO.NET系列之Connection对象 ADO.NET系列之Command对象 ADO.NET系列之DataAdapter对象 ADO.NET系列之事务和调用存储过程 上一篇<ADO.NE ...

  2. ajax C# webapi上传图片

    html ajax上传图片到服务器 后端采用asp.net webapi 前端有各种现实上传图片的控件,样式可以做的很美观.我这里只用基本的样式做图片上传. 前端代码 <input name=& ...

  3. DataAnnotations 验证

    转自:http://blog.sina.com.cn/s/blog_c21a857b0102wcus.html 常用的 DataAnnotations 1.Required :属性值必须非空或者不能只 ...

  4. Visual Studio 编译信息细度显示设置

    visual studio 项目在编译时,可根据调试需要设置output窗口输出内容的详细程度,这对于bug或warning的解决具有很大帮助.具体设置如下: 依次点击:"Tools&quo ...

  5. ZZNU 2076(退役学长最后的神功 zz题)

    题目链接:http://acm.zznu.edu.cn/problem.php?pid=2076 输入一个T表示有T个样例每组实例一个整数n(0〈n〈1000接下来输入2*n个数字,代表一个2*n的矩 ...

  6. [JavaScript] 将字符串数组转化为整型数组

    var dataStr="1,2,3,4,5";//原始字符串 var dataStrArr=dataStr.split(",");//分割成字符串数组 var ...

  7. [bug]小程序弹出层滚动穿透问题修复

    如题,解决方案有两种: 1.如果弹出层没有滚动事件,就直接在蒙板和弹出层上加 catchtouchmove;(方便快捷) <template name="popup-modal&quo ...

  8. D08——C语言基础学PYTHON

    C语言基础学习PYTHON——基础学习D08 20180829内容纲要: socket网络编程 1  socket基础概念 2  socketserver 3  socket实现简单的SSH服务器端和 ...

  9. Centos7下CPU内存等资源监控

    1.查看内存使用情况: [root@takeout web-takeout]# free -m total used free shared buff/cache available Mem: 378 ...

  10. linux centos7 防火墙及端口开放相关命令

    一.防火墙相关命令 1.查看防火墙状态 : systemctl status firewalld.service 注:active是绿的running表示防火墙开启 2.关闭防火墙 :systemct ...