【题解】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]转盘[结论+线段树]
题意 题目链接 分析 首先要发现一个结论:最优决策一定存在一种 先在出发点停留之后走一圈 的情况,可以考虑如下证明: 如果要停留的话一定在出发点停留,这样后面的位置更容易取到. 走超过两圈的情况都可以 ...
随机推荐
- 【caffe范例详解】 - 1.Classification分类
1. 安装 首先,导入numpy和matplotlib库 # numpy是常用的科学计算库,matplot是常用的绘图库 import numpy as np import matplotlib.py ...
- spring cloud 服务注册中心eureka高可用集群搭建
spring cloud 服务注册中心eureka高可用集群搭建 一,准备工作 eureka可以类比zookeeper,本文用三台机器搭建集群,也就是说要启动三个eureka注册中心 1 本文三台eu ...
- windows安装logstash-input-jdbc并使用其导入MMSQL数据
1.安装logstash 2.修改logstash 文件夹下Gemfile文件 将source改为:https://gems.ruby-china.org 3.进入bin目录 执行logstash-p ...
- 一些窍门 drawable
java.lang.Object android.graphics.drawable.DrawableKnown Direct Subclasses BitmapDrawable, C ...
- 【springboot-01】整合quartz
1.什么是quartz? quartz是一个开源的定时任务框架,具备将定时任务持久化至数据库以及分布式环境下多节点调度的能力.当当的elastic-job便是以quartz为基础,结合zookeepe ...
- leetcode-生成括号(回溯算法)
转载出处:https://blog.csdn.net/yanerhao/article/details/68561290 生成括号 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生 ...
- [Clr via C#读书笔记]Cp15枚举和位标识
Cp15枚举和位标识 枚举类型 本质是结构,符号名称-值:好处显而易见:System.Enum;值类型: 编译的时候,符号会转换为常量字段: 枚举支持很多方法和成员: 位标识bit flag 判断和设 ...
- linux 命令行基础
命令行基础 一些名词 「图形界面」 「命令行」 「终端」 「shell」 「bash」 安装使用 Windws: 安装git, 打开 gitbash Linux 打开终端 Mac 打开终端 基本命令 ...
- 线性代数之——正交矩阵和 Gram-Schmidt 正交化
这部分我们有两个目标.一是了解正交性是怎么让 \(\hat x\) .\(p\) .\(P\) 的计算变得简单的,这种情况下,\(A^TA\) 将会是一个对角矩阵.二是学会怎么从原始向量中构建出正交向 ...
- HDU 3262/POJ 3829 Seat taking up is tough(模拟+搜索)(2009 Asia Ningbo Regional)
Description Students often have problems taking up seats. When two students want the same seat, a qu ...