「HNOI2018」转盘
「HNOI2018」转盘
现场推出了大部分结论但是只写了 \(40\) 分暴力,被贺指导踩爆,现在还有点怀念 HNOI2018 贺指导对着镜子荒野行动的日子,那几天他云球迷瞎**指点篮球,被送上指导称号一个。
解题思路:
可以大力证明一定存在一种最优解只需要走一圈,假设存在一个最优解在某个时刻已经走了一圈回到出发点还剩下一些点没有被标记,那么最终还需要走到这些点标记一遍,这样的时间开销和在需要被标记的点之前等到它可以再走是等价的,所以一定存在一种最优解是在起始点等若干时刻然后一遍走完的。
于是可以把环倍长为 \(T_1,T_2\dots T_{2n}\) ,枚举一个起始点 \(1\leq s \leq n\) ,贡献就是
\\ ans = n-1+\min_{1\leq s \leq n}(s+\max_{s\leq i < s+n} (T_i-i))
\]
这个东西是所有长度为 \(n\) 的区间的贡献的 \(\min\) ,不太好维护,观察发现每一个区间后面的元素必然会小于区间内元素的 \(\max\) ,因为后面的元素都是倍长后没有被用到的 \(T_{i+n}\) ,显然 \(T_{i+n}-i-n<T_i-i\) 。
于是问题就转化为对于每一个后缀算贡献取 \(\min\) ,经典线段树维护单调栈求解即可。
具体来说,令 \(Ans(l,r)\) 为左端点在 \([l,mid]\) 的所有后缀贡献的 \(\min\) ,再维护一下区间 \(\max\) ,那么可以线段树二分找到 \(\max[mid+1,r]\) 在 \([l,mid]\) 中的位置 \(pos\) ,那么 \(pos\) 及以后的贡献是 \(pos+\max[mid+1,r]\) ,\(pos\) 之前的贡献就是那个节点原先的 \(Ans\) 。
这样搞一搞更新需要额外的一个 \(\log\) ,总时间复杂度 \(\mathcal O(n\log^2n)\) 。
code
/*program by mangoyang*/
#pragma GCC optimize("O2", "Ofast")
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 200005;
int t[N], n, m, p;
namespace Seg{
#define lson (u << 1)
#define rson (u << 1 | 1)
#define mid ((l + r) >> 1)
int mx[N<<2], s[N<<2];
inline int find(int u, int l, int r, int x){
if(l == r) return l + max(mx[u], x);
if(mx[rson] >= x)
return min(s[u], find(rson, mid + 1, r, x));
return min(mid + 1 + x, find(lson, l, mid, x));
}
inline void update(int u, int l, int r){
mx[u] = max(mx[lson], mx[rson]);
s[u] = find(lson, l, mid, mx[rson]);
}
inline void build(int u, int l, int r){
if(l == r) return (void) (mx[u] = t[l], s[u] = l + t[l]);
build(lson, l, mid), build(rson, mid + 1, r);
update(u, l, r);
}
inline void modify(int u, int l, int r, int pos, int x){
if(l == r) return (void) (mx[u] = x, s[u] = l + x);
if(pos <= mid) modify(lson, l, mid, pos, x);
else modify(rson, mid + 1, r, pos, x);
update(u, l, r);
}
}
int main(){
read(n), read(m), read(p);
for(int i = 1; i <= n; i++) read(t[i]);
for(int i = 1; i <= n; i++) t[i+n] = t[i];
for(int i = 1; i <= 2 * n; i++) t[i] -= i;
Seg::build(1, 1, 2 * n);
int lastans = Seg::s[1] + n - 1;
printf("%d\n", lastans);
for(int i = 1, x, y; i <= m; i++){
read(x), read(y), x ^= lastans * p, y ^= lastans * p;
Seg::modify(1, 1, 2 * n, x, y - x);
Seg::modify(1, 1, 2 * n, x + n, y - x - n);
printf("%d\n", lastans = Seg::s[1] + n - 1);
}
return 0;
}
「HNOI2018」转盘的更多相关文章
- Loj #2495. 「AHOI / HNOI2018」转盘
Loj #2495. 「AHOI / HNOI2018」转盘 题目描述 一次小 G 和小 H 原本准备去聚餐,但由于太麻烦了于是题面简化如下: 一个转盘上有摆成一圈的 \(n\) 个物品(编号 \(1 ...
- 「AHOI / HNOI2018」转盘 解题报告
「AHOI / HNOI2018」转盘 可能是我语文水平不太行... 首先可以猜到一些事实,这个策略一定可以被一个式子表示出来,不然带修修改个锤子. 然后我们发现,可以枚举起点,然后直接往前走,如果要 ...
- 「HNOI2018」毒瘤
「HNOI2018」毒瘤 解题思路 先考虑只有一棵树的情况,经典独立集计数. \[ dp[u][0]=\prod (dp[v][0]+dp[v][1]) \\ dp[u][1]=\prod dp[v] ...
- 「HNOI2018」游戏
「HNOI2018」游戏 解题思路 首先没有锁上的门可以缩点缩掉,然后对于一扇锁上的门,如果钥匙在左边,那么右边就永远不可能到达左边,同理如果钥匙在右边,左边就永远不可能到达右边. 然后考虑一个暴力的 ...
- 【LOJ】#2495. 「AHOI / HNOI2018」转盘
题面 题解 考虑我肯定是从一个人出发,开始依次标记,而不会跳过某个人,因为如果我跳过了,那么我之后回来还需要标记它,比不上我等完它再一直走到最后(因为多了走一圈之后走回它的代价) 我们倍长整个序列,我 ...
- Loj #2494. 「AHOI / HNOI2018」寻宝游戏
Loj #2494. 「AHOI / HNOI2018」寻宝游戏 题目描述 某大学每年都会有一次 Mystery Hunt 的活动,玩家需要根据设置的线索解谜,找到宝藏的位置,前一年获胜的队伍可以获得 ...
- loj #2510. 「AHOI / HNOI2018」道路
#2510. 「AHOI / HNOI2018」道路 题目描述 W 国的交通呈一棵树的形状.W 国一共有 n−1 个城市和 nnn 个乡村,其中城市从 111 到 n−1 编号,乡村从 111 到 n ...
- loj #2509. 「AHOI / HNOI2018」排列
#2509. 「AHOI / HNOI2018」排列 题目描述 给定 nnn 个整数 a1,a2,…,an(0≤ai≤n),以及 nnn 个整数 w1,w2,…,wn.称 a1,a2,…,an 的 ...
- loj #2508. 「AHOI / HNOI2018」游戏
#2508. 「AHOI / HNOI2018」游戏 题目描述 一次小 G 和小 H 在玩寻宝游戏,有 nnn 个房间排成一列,编号为 1,2,…,n,相邻房间之间都有 111 道门.其中一部分门上有 ...
随机推荐
- OpenCV LIBTIFF_4.0 link errors
以前用Caffe用的好好的,今天重装后居然报了很多这样的错误 /usr/lib/libopencv_highgui.so.' 1> /usr/lib/libopencv_highgui.so.' ...
- webpack详解
webpack是现代前端开发中最火的模块打包工具,只需要通过简单的配置,便可以完成模块的加载和打包.那它是怎么做到通过对一些插件的配置,便可以轻松实现对代码的构建呢? webpack的配置 const ...
- VUE项目用hbuilder 打包为手机APP
一.测试项目是否可以正确运行 指令:npm run dev 首先我们先建立一个vue的项目,本人用的是vue-cli随便建立的,然后运行项目 不必非得是像我这样的,这一步的目的只是测试一下咱们的 ...
- 音频自动增益 与 静音检测 算法 附完整C代码【转】
转自:https://www.cnblogs.com/cpuimage/p/8908551.html 前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用 ...
- aarch64_l1
L-function-1.23-18.fc26.aarch64.rpm 2017-02-14 08:01 139K fedora Mirroring Project L-function-devel- ...
- 使用pandas把mysql的数据导入MongoDB。
使用pandas把mysql的数据导入MongoDB. 首先说下我的需求,我需要把mysql的70万条数据导入到mongodb并去重, 同时在第二列加入一个url字段,字段的值和第三列的值一样,代码如 ...
- java基础26 线程的通讯;wait()、notify()、notifyAll()等方法
线程的通讯:一个线程完成了自己的任务时,要通知另一个线程去完成另一个任务 1.1.方法 wait():等待.如果线程执行到了wait()方法,那么该线程会进入等待状态,等待状态下的线程必须要被其他线程 ...
- UFLDL(五)自编码算法与稀疏性
新教程内容太繁复,有空再看看,这节看的还是老教程: http://ufldl.stanford.edu/wiki/index.php/%E8%87%AA%E7%BC%96%E7%A0%81%E7%AE ...
- 20155309 《Java程序设计》实验三(Java面向对象程序设计)实验报告
一.实验内容及步骤 (一)编码标准 在IDEA中使用工具(Code->Reformate Code)把代码重新格式化. (二)在码云上把自己的学习搭档加入自己的项目中,确认搭档的项目加入自己后, ...
- 微信小程序实现左滑删除源码
左滑删除效果在app的交互方式中十分流行,比如全民应用微信 微信左滑删除 再比如曾引起很大反响的效率app Clear Clear左滑删除 从技术上来说,实现这个效果并不困难,响应一下滑动操作,移动一 ...