[CQOI2014]排序机械臂
时间:2021-07-20
本文章向大家介绍 [CQOI2014]排序机械臂,主要包括 [CQOI2014]排序机械臂使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
\(Solution\)
非常板的一道题,支持区间翻转
本人采用 \(\text{FQH-Treap}\) 实现,按排名分裂
题目显然可以转化为找区间最小值的位置,只要每次把当前最小值扔出 \(\text{Treap}\)
为处理最小值相同的情况,就离散化处理
然后维护子树最小值就对了
\(\text{Code}\)
#include <cstdio>
#include <algorithm>
#include <ctime>
#define re register
using namespace std;
typedef long long LL;
const int N = 1e5 + 5;
int n, b[N], rt, ls[N], rs[N], val[N], mi[N], rnd[N], siz[N], tag[N];
struct nod{int v, id;}a[N];
inline bool cmp(nod a, nod b){return (a.v < b.v ? 1 : (a.v == b.v ? a.id < b.id : 0));}
inline int new_node(int x)
{
static int size = 0;
val[++size] = x, mi[size] = x, rnd[size] = rand(),
siz[size] = 1, ls[size] = rs[size] = tag[size] = 0;
return size;
}
inline void pushup(int p)
{
siz[p] = siz[ls[p]] + siz[rs[p]] + 1, mi[p] = val[p];
if (ls[p]) mi[p] = min(mi[p], mi[ls[p]]);
if (rs[p]) mi[p] = min(mi[p], mi[rs[p]]);
}
inline void pushdown(int p)
{
if (!p || !tag[p]) return;
tag[p] = 0, swap(ls[p], rs[p]);
if (ls[p]) tag[ls[p]] ^= 1;
if (rs[p]) tag[rs[p]] ^= 1;
}
void split(int p, int k, int &x, int &y)
{
if (!p) return void(x = y = 0);
pushdown(p);
if (k <= siz[ls[p]]) y = p, split(ls[p], k, x, ls[y]);
else x = p, split(rs[p], k - siz[ls[p]] - 1, rs[x], y);
pushup(p);
}
int merge(int x, int y)
{
if (!x || !y) return x | y;
pushdown(x), pushdown(y);
if (rnd[x] < rnd[y]){rs[x] = merge(rs[x], y), pushup(x); return x;}
ls[y] = merge(x, ls[y]), pushup(y); return y;
}
inline int find(int p)
{
int k = 1;
while (1)
{
pushdown(p);
if (ls[p] && mi[ls[p]] == mi[p]) p = ls[p];
else if (rs[p] && mi[rs[p]] == mi[p]) k += siz[ls[p]] + 1, p = rs[p];
else return k + siz[ls[p]];
}
}
int main()
{
srand((unsigned)time(NULL));
scanf("%d", &n);
for(re int i = 1; i <= n; i++) scanf("%d", &a[i].v), a[i].id = i;
sort(a + 1, a + n + 1, cmp);
for(re int i = 1; i <= n; i++) b[a[i].id] = i;
for(re int i = 1; i <= n; i++) rt = merge(rt, new_node(b[i]));
for(re int i = 1; i <= n; i++)
{
int x, y, z, o = find(rt);
printf("%d ", o + i - 1);
split(rt, o, x, y), split(x, o - 1, x, z);
tag[x] ^= 1, rt = merge(x, y);
}
}
原文地址:https://www.cnblogs.com/leiyuanze/p/15037194.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 提高单细胞分析准确度的工具之一:Self-assembling manifolds
- 一不小心肝出了4W字的Redis面试教程
- 双向LSTM-CRF模型用于序列标注
- 容器服务 TKE 上服务暴露的几种方式
- 【论文分享】ACL 2020 信息抽取任务中的新动向
- 工匠人iOS 代码规范
- 写一个通用的幂等组件,我觉得很有必要
- PC性能监测工具,您不可或缺的好帮手~~
- 特征工程之处理时间序列数据
- Matplotlib中的“plt”和“ax”到底是什么?
- 使用深度学习模型创作动漫故事,比较LSTM和GPT2的文本生成方法
- 聊聊BitCaskLock
- LightGBM的参数详解以及如何调优
- 聊聊BitCaskKeyDir
- 使用2D卷积技术进行时间序列预测