【题解】HNOI2018转盘
何学长口中所说的‘一眼题’……然而实际上出出来我大HN全省也只有一个人A……
首先我们需要发现一个性质:我们永远可以在最后一圈去标记所有的物品。倘若我们反复转圈,那么这完全是可以省下来的。所以我们破环为链,以\(S\) 物品作为第一个被访问的节点时所需要的时间就是 \( max(T_{x} - x) + S \),其中 \( S <= x <= S + n - 1\)。问题转化为如何使用数据结构来维护这些值得最小值。注意到 \(T_{x} - x \)都只与 \(x\) 有关,我们就他将它们合为一个变量 :\(A_{x} = T_{x} - x\)。由于 \(T_{x} == T_{x + n}\),所以 \(A_{x} > A_{x +n}\) 。所以若 \(A_{x} = max(A_{j}) (S <= j <= S + n - 1)\),那么 \(A_{x} = max(A_{j}) (S <= j <= 2 * n)\)。这里应该是一个启示吧,有时候观察数组的性质,不仅仅缩小范围是有效的,实际上扩大范围为前缀 / 后缀也一样是非常重要的一个方面。那么这个时候我们就发现:这实际上对于答案可能产生贡献的就是所有从后往前比任何一个元素都要大的 \(A_{x}\) 啦。
使用线段树我们可以维护这样的一个单调栈,由于我们已经固定了 \(A_{x}\),我们只需要使得 \(S\) 最小即可。显然\(S\)尽量小就应该是 \(x\) 左侧第一个比它大的数的下标+1。使用线段树维护这个信息的最大值即可(楼房重建问题)。
其中 \(mx\) 维护区间内 \(A_{x}\) 的最大值,\(mn\) 维护区间内 \(A_{x} + S\) 的最小值, \(rec\) 记录区间内只考虑左边区间 & 右边区间最大值的贡献 (但考虑右边对于左边的限制) 。
#include <bits/stdc++.h>
using namespace std;
#define maxn 1000000
#define INF 999999999
int n, m, P, N, ans, T[maxn];
int mn[maxn], mx[maxn], rec[maxn]; int read()
{
int x = , k = ;
char c; c = getchar();
while(c < '' || c > '') { if(c == '-') k = -; c = getchar(); }
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x * k;
} int Query(int p, int l, int r, int K)
{
if(l == r)
{
if(mx[p] > K) return min(mn[p], K + l + );
else return INF;
}
int mid = (l + r) >> ;
if(mx[p << | ] <= K) return Query(p << , l, mid, K);
else return min(rec[p], Query(p << | , mid + , r, K));
} void Push_Up(int p, int l, int r)
{
int ls = p << , rs = p << | ;
mx[p] = max(mx[ls], mx[rs]);
int mid = (l + r) >> ;
mn[p] = min(rec[p] = Query(ls, l, mid, mx[rs]), mn[p << | ]);
} void Build(int p, int l, int r)
{
if(l == r)
{
mx[p] = T[l] - l; mn[p] = T[l];
return;
}
int mid = (l + r) >> ;
Build(p << , l, mid); Build(p << | , mid + , r);
Push_Up(p, l, r);
} void Update(int p, int l, int r, int x)
{
if(l == r)
{
mx[p] = T[l] - l; mn[p] = T[l];
return;
}
int mid = (l + r) >> ;
if(x <= mid) Update(p << , l, mid, x);
else Update(p << | , mid + , r, x);
Push_Up(p, l, r);
} int main()
{
n = read(), m = read(), P = read(), N = * n;
for(int i = ; i <= n; i ++) T[i] = read();
for(int i = ; i <= n; i ++) T[i + n] = T[i];
Build(, , N);
printf("%d\n", ans = min(mx[] + , rec[]) + n - );
for(int i = ; i <= m; i ++)
{
int x = read(), y = read();
if(P) x ^= ans, y ^= ans;
T[x] = T[x + n] = y;
Update(, , N, x); Update(, , N, x + n);
printf("%d\n", ans = min(mx[] + , rec[]) + n - );
}
return ;
}
【题解】HNOI2018转盘的更多相关文章
- 【BZOJ5286】[HNOI2018]转盘(线段树)
[BZOJ5286][HNOI2018]转盘(线段树) 题面 BZOJ 洛谷 题解 很妙的一道题目啊.(全世界除了我这题都有40分,就我是一个状压选手 首先来发现一些性质,我们走一圈一定不会更差. 为 ...
- 5286: [Hnoi2018]转盘
5286: [Hnoi2018]转盘 链接 分析: $\min\limits_{i=1}^n \{ \max\limits_{j=i}^{i + n - 1} \{ a_{j}+i \} \} +n- ...
- [HNOI2018]转盘
[HNOI2018]转盘 给你一个 \(n\) 元环, 你可以在 \(0\) 时刻从任意一个位置出发, 每一秒可以选择往后或者留在原地每个点有个参数 \(T_i\) , 当你走到 \(i\) 的时间 ...
- [BZOJ5286][洛谷P4425][HNOI2018]转盘(线段树)
5286: [Hnoi2018]转盘 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 15 Solved: 11[Submit][Status][Di ...
- BZOJ5286: [Hnoi2018]转盘 (线段树)
题意 给你绕成一圈的物品共 \(n\) 个 , 然后从其中一个开始选 , 每次有两种操作 , 一是继续选择当前物品 , 二是选择这个后一个物品 . 选择后一个物品要求当前的时刻大于后一个的 \(T_i ...
- bzoj5286 [Hnoi2018]转盘
题目描述: bz luogu 题解: 看了半个晚上终于明白了. 首先最优决策一定有:在起始点停留一段时间然后一直前进. 解释网上有很多,在这里不赘述了. (由于是环,先把$T$数组倍长.) 首先基于决 ...
- bzoj 5286: [Hnoi2018]转盘
Description Solution 首先注意到一个点不会走两次,只会有停下来等待的情况,把序列倍长 那么如果枚举一个起点\(i\),答案就是 \(min(max(T[j]+n-(j-i)-1)) ...
- BZOJ.5286.[AHOI/HNOI2018]转盘(线段树)
BZOJ LOJ 洛谷 如果从\(1\)开始,把每个时间\(t_i\)减去\(i\),答案取决于\(\max\{t_i-i\}\).记取得最大值的位置是\(p\),答案是\(t_p+1+n-1-p=\ ...
- [HNOI2018]转盘[结论+线段树]
题意 题目链接 分析 首先要发现一个结论:最优决策一定存在一种 先在出发点停留之后走一圈 的情况,可以考虑如下证明: 如果要停留的话一定在出发点停留,这样后面的位置更容易取到. 走超过两圈的情况都可以 ...
随机推荐
- Objective-C 内存管理和ARC
内存管理 范围: 任何继承了NSObject的对象 对基本数据类型无效 原理: 每个对象内部都保存了一个与之相关联的整数 称为引用计数器 1.计数器的基本操作 当使用alloc new或者copy创建 ...
- Python递归算法入门
递归是一种算法,它在编程里面有着广泛的应用: 1. 递归必须满足哪两个基本条件? 一.函数调用自身 二.设置了正确的返回条件 2. 思考一下,按照递归的特性,在编程中有没有不得不使用递归的情况? 答: ...
- JavaScript基本概念(1)-声明提升
声明提升: function > var > other var提升的时候,只是声明提升,但是赋值还是会在原来的位置. Javascript Hoisting:In javascript, ...
- 基于 CPython 解释器,为你深度解析为什么Python中整型不会溢出
前言 本次分析基于 CPython 解释器,python3.x版本 在python2时代,整型有 int 类型和 long 长整型,长整型不存在溢出问题,即可以存放任意大小的整数.在python3后, ...
- JS原型链与继承别再被问倒了
原文:详解JS原型链与继承 摘自JavaScript高级程序设计: 继承是OO语言中的一个最为人津津乐道的概念.许多OO语言都支持两种继承方式: 接口继承 和 实现继承 .接口继承只继承方法签名,而实 ...
- python基本数据类型——集合
集合 无序可变序列,集合中元素不允许重复,即每个元素都是唯一的 集合中的元素按照升序排列 # 创建集合 >>aset = set([0,2,4,5,7,2,3,5,9,0]) >&g ...
- 【QT】宏
宏 Q_CORE_EXPORT _CORE_EXPORT 其实是一个宏,用来说明这是一个动态库导出类.QT是个跨平台的库,而不同的操作系统,不同的编译器,对动态库的导出说明是不一样的,比如,在wind ...
- Ubuntu—安装并运行sublime
step1 到官网看看 https://www.sublimetext.com/3 step2 根据版本选择,我的是32位的 step3 ubuntu终端安装 (1)切换目录 -$ cd /opt ...
- Deep Residual Learning for Image Recognition论文笔记
Abstract We present a residual learning framework to ease the training of networks that are substant ...
- selenium元素定位不到之iframe---基于python
我们在使用selenium的18中定位方式的时候,有时会遇到定位不上的问题,今天我们就来说说导致定位不上的其中一个原因---iframe 问题描述:通过firebug查询到相应元素的id或name等, ...