题意大概是这样,「每次操作选出区间中的一个 LIS(strictly),满足其开端是极靠近左端点且大于 \(A\) 的位置,答案即这个 LIS 的末尾,做一个轮换后弹出序列末端」。

首先做几个观察。

Observation 1:每次被弹出的都是区间最大值。

证明:显然,你考虑有一个最大的值在钦定的 LIS 的前或后,都会被先行选择 / 扩展进来。

Observation 2(key observation):如果对一个区间插入若干个值,插入顺序不影响最终序列的长相。

证明:每次插入进去的值不可能成为序列的最大值,所以弹出的数固定。并且插入进的数是根据严格偏序关系插进去的,所以顺序不影响长相。

仅凭以上两个观察,此题的奇怪操作怎么看也不像是个 \({\rm polylog}\),选择对序列做 Sqrt Decomposition,接下来我们探讨整块间的处理方式和散块的做法,因为操作的特殊性我们并不需要做 8 种情况的伞兵讨论。

  • 整块间:你考虑每个整块上维护一个大根堆,然后整块的后继继承该整块的最大值,该整块去除其最大值即可;
  • 散块:把所有需要插入的元素存一个懒标在右边散块放出来,因为 Observation 2,我们贪心优先把值较小的懒标放出去即可。
#include <bits/stdc++.h>
template <class T> inline void chmax(T& a, const T b) { a = a > b ? a : b; }
template <class T> inline void chmin(T& a, const T b) { a = a < b ? a : b; }
inline long long rd() {
long long x = 0; bool f = 0; char ch = getchar();
while (ch < '0' || ch > '9') f |= (ch == '-'), ch = getchar();
while (ch >= '0' && ch <= '9') x = x * 10 + (ch & 15), ch = getchar();
return f ? -x : x;
}
/** @brief
* 选出一个 LIS,满足开始是极靠近 l 的大于 A 的位置,答案即序列的末端,然后用 A 替换序列开头,做一个轮换,弹出序列末端
* Observation 1:每次被弹出的都是区间最大值
* Trick:序列分块
* Section 1:整块
* 整块上维护一个堆,整块间下一块继承上一块的最大值
* Section 2:散块
* 维护一个小根堆,每次散块暴力重构
* key observation:插入顺序不影响序列的长相
*/
constexpr int BS = 650;
int n, m, a[400100], pos[400100];
int L[660], R[660];
std::priority_queue<int> max[660];
std::priority_queue<int, std::vector<int>, std::greater<int>> tag[660];
void push(int i, int x) { max[i].emplace(x); }
void setBound(int i) { L[i] = (i - 1) * BS + 1, R[i] = i * BS; }
int Qry(int i, int l, int r, int x) {
if (tag[i].size()) {
for (int j = L[i]; j <= R[i]; ++j)
if (int t = a[j]; tag[i].top() < t)
a[j] = tag[i].top(), tag[i].pop(), tag[i].emplace(t);
}
while (max[i].size()) max[i].pop();
while (tag[i].size()) tag[i].pop();
for (int j = l; j <= r; ++j)
if (a[j] > x) std::swap(a[j], x);
for (int f = L[i]; f <= R[i]; ++f) push(pos[L[i]], a[f]);
return x;
}
int Mdf(int i, int x) {
if (x >= max[i].top()) return x;
int res = max[i].top(); max[i].pop();
max[i].emplace(x), tag[i].emplace(x);
return res;
}
signed main() {
n = rd(), m = rd();
for (int i = 1; i <= n; ++i)
push(pos[i] = (i - 1) / BS + 1, a[i] = rd());
for (int i = 1; i <= pos[n]; ++i) setBound(i);
R[pos[n]] = n;
for (int l, r, a; m--;) {
l = rd(), r = rd(), a = rd();
if (pos[l] == pos[r] && l <= r) printf("%d\n", Qry(pos[l], l, r, a));
else {
a = Qry(pos[l], l, R[pos[l]], a);
for (int u = pos[l] + 1 > pos[n] ? 1 : pos[l] + 1; u != pos[r]; u = u + 1 > pos[n] ? 1 : u + 1)
a = Mdf(u, a);
printf("%d\n", Qry(pos[r], L[pos[r]], r, a));
}
}
return 0;
}

「joisc2016 - D3T2」回転寿司的更多相关文章

  1. 「Luogu P1210」回文检测 解题报告

    题面 这是一道诡异的黄题 居然让你求一串吧啦吧啦的东西中 字母(大小写)最长的回文串的长度,还要输出完整的串 吐血 思路: 保持淡定,我们啥都不会,就会Manacher,那就用Manacher大法! ...

  2. 「Luogu P4987」回文项链 解题报告

    题面 求环中的长度为k(k为奇数)且回文中心不同的回文串个数 思路: 刚学manacher算法,就送上一道模板题,此题注重对manacher算法的理解 Manacher,但是不用插入其他符号,因为k是 ...

  3. 「Luogu P1435」回文字串 解题报告

    题面 主要大衣大意: 给定一个字符串,求至少加入多少个字符才能使字符串变成回文字符串 下面就是我一本正经的胡说八道题解 思路: 很显然,这应该是一道典型的最长公共子序列的题目 因此,主要思想就是DP ...

  4. Solution -「LOJ #141」回文子串 ||「模板」双向 PAM

    \(\mathcal{Description}\)   Link.   给定字符串 \(s\),处理 \(q\) 次操作: 在 \(s\) 前添加字符串: 在 \(s\) 后添加字符串: 求 \(s\ ...

  5. 图解最长回文子串「Manacher 算法」,基础思路感性上的解析

    问题描述: 给你一个字符串 s,找到 s 中最长的回文子串. 链接:https://leetcode-cn.com/problems/longest-palindromic-substring 「Ma ...

  6. 如何对抗 WhatsApp「蓝色双勾」-- 3 个方法让你偷偷看讯息

    WhatsApp 强制推出新功能「蓝色双勾 (✔✔)」 ,让对方知道你已经看过讯息.一众用户反应极大,因为以后不能再藉口说未看到讯息而不回覆.究竟以后 WhatsApp 是否真的「更难用」? 幸好还有 ...

  7. ListView与.FindControl()方法的简单练习 #2 -- ItemUpdting事件中抓取「修改后」的值

    原文出處  http://www.dotblogs.com.tw/mis2000lab/archive/2013/06/24/listview_itemupdating_findcontrol_201 ...

  8. 「前端开发者」如何把握住「微信小程序」这波红利?

    由于前两周一直在老家处理重要事情,虽然朋友圈被「微信小程序」刷爆了,但并没有时间深入了解. 昨天回广州之后,第一件事情就是把「微信小程序」相关的文章.开发文档.设计规范全部看了一遍,基本上明白了「微信 ...

  9. 当你「ping 一下」的时候,你知道它背后的逻辑吗?

    我们在遇到网络不通的情况,大家都知道去 ping 一下,看一下网络状况.那你知道「ping」命令后背的逻辑是什么吗?知道它是如何实现的吗? 一.「ping」命令的作用和原理? 简单来说,「ping」是 ...

  10. 「Android 开发」入门笔记

    「Android 开发」入门笔记(界面编程篇) ------每日摘要------ DAY-1: 学习笔记: Android应用结构分析 界面编程与视图(View)组件 布局管理器 问题整理: Andr ...

随机推荐

  1. 数据科学工具 Jupyter Notebook 教程(一)

    ipython notebook 是一个基于浏览器的 python 数据分析工具,使用起来非常方便,具有极强的交互方式和富文本的展示效果.jupyter 是它的升级版,它的安装也非常方便,一般 Ana ...

  2. C++面试八股文:override和finial关键字有什么作用?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第22面: (二师兄好苦逼,节假日还在面试...) 面试官:C++的继承了解吗? 二师兄:(不好意思,你面到我的强项了..)了解一些. 面试官:什么是 ...

  3. 有哪些ASIC加速技术可以实现低功耗运行?

    目录 文章主题: 10. 有哪些ASIC加速技术可以实现低功耗运行? 背景介绍:随着移动设备.物联网.云计算等应用场景的不断增长,功耗成为了一个日益重要的技术问题.为了在移动设备上实现更长时间的运行, ...

  4. 信创优选,国产开源,Solon v2.3.6 发布

    Solon 是什么开源项目? 一个,Java 新的生态型应用开发框架.它从零开始构建,有自己的标准规范与开放生态(历时五年,已有全球第二级别的生态).与其他框架相比,它解决了两个重要的痛点:启动慢,费 ...

  5. Linux系统运维之Zookeeper集群配置

    一.简介 ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.ZooKeeper的目标就是封装好复杂易 ...

  6. 【Kubernetes】yaml文件编写 -- 持续更新

    K8S通过yaml格式的声明式API与资源对象交互 API版本由apiVersion字段指定,API对象类型由kind字段指定 除此之外,每个API对象有三大类属性: metadata:元数据 spe ...

  7. Java_Day16_作业

    A:简答题 1.请把我们讲解过的所有类中的方法在API中找到,并使用自己的话进行描述 答案: Map public V put(K key, V value): public void clear() ...

  8. grafana 容器无法启动,打印权限问题

    报错日志 open /var/lib/grafana/alerting/1/notifications: permission denied 问题原因 sudo chown -R docker: /v ...

  9. Linux shell:根据盘符定位硬盘在服务器上的位置

    disk-light.sh #!/bin/bash t_dev=$1 [ -b "$t_dev" ] || { echo "-b failed: $t_dev" ...

  10. 天地图三维帮助文档(Cesium)

    https://blog.csdn.net/Tmraz/article/details/114977652