P2710 数列[fhq treap]
调了一辈子的fhq treap…
7个操作…
其中三个查询 单点查询其实可以和区间查询写成一个(
fhq treap 的修改操作大概就是 \(split\) 完了然后把修改区间的根 打上标记 等着下传就完事了…
那这题没了…我给个好一点的小数据…反正我照着这个调了挺久的…
.in
50 10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
GET 13
REVERSE 15 1
MAKE-SAME 1 1 3
REVERSE 21 8
GET-SUM 22 3
MAX-SUM 32 2
GET 8
DELETE 4 9
GET 36
REVERSE 34 2
.out
13
78
65
8
45
#include<cstdio>
#include<cstdlib>
#include<string>
#include<iostream>
int min(int x , int y) {
return x < y ? x : y ;
}
int max(int x , int y) {
return x > y ? x : y ;
}
void swap(int & x , int & y) {
x ^= y ^= x ^= y ;
}
int read() {
int x = 0 , f = 1 ;
char c = getchar() ;
while(c < 48 || c > 57) {
if(c == '-') f = 0 ;
c = getchar() ;
}
while(c >= 48 && c <= 57) {
x = (x << 1) + (x << 3) + (c & 15) ;
c = getchar() ;
}
return f ? x : -x ;
}
int n , m , rt , cnt ;
constexpr int N = 2e6 + 10 ;
constexpr int lim = 2333 ;
int a[N] ;
int rnd[N] , val[N] , sum[N] , sz[N] , ls[N] , rs[N] ;
int lmax[N] , rmax[N] , mx[N] ;
int tag[N] , rev[N] ;
void pushup(int o) {
sz[o] = sz[ls[o]] + sz[rs[o]] + 1 ;
sum[o] = sum[ls[o]] + sum[rs[o]] + val[o] ;
lmax[o] = max(lmax[ls[o]] , sum[ls[o]] + max(0 , lmax[rs[o]]) + val[o]) ;
rmax[o] = max(rmax[rs[o]] , sum[rs[o]] + max(0 , rmax[ls[o]]) + val[o]) ;
mx[o] = max(0 , rmax[ls[o]]) + max(0 , lmax[rs[o]]) + val[o] ;
if(ls[o]) mx[o] = max(mx[o] , mx[ls[o]]) ;
if(rs[o]) mx[o] = max(mx[o] , mx[rs[o]]) ;
}
void reverse(int o) {
swap(ls[o] , rs[o]) ;
swap(lmax[o] , rmax[o]) ;
rev[o] ^= 1 ;
}
void cover(int o , int v) {
val[o] = tag[o] = v ;
sum[o] = v * sz[o] ;
lmax[o] = rmax[o] = mx[o] = max(sum[o] , v) ;
}
void pushdown(int o) {
if(rev[o]) {
if(ls[o]) reverse(ls[o]) ;
if(rs[o]) reverse(rs[o]) ;
rev[o] ^= 1 ;
}
if(tag[o] != lim) {
if(ls[o]) cover(ls[o] , tag[o]) ;
if(rs[o]) cover(rs[o] , tag[o]) ;
tag[o] = lim ;
}
}
int newnode(int k) {
++ cnt ;
rnd[cnt] = rand() ;
val[cnt] = sum[cnt] = k ;
lmax[cnt] = rmax[cnt] = mx[cnt] = k ;
sz[cnt] = 1 ;
tag[cnt] = lim ;
ls[cnt] = rs[cnt] = 0 ;
return cnt ;
}
int merge(int x , int y) {
if(! x || ! y) return x | y ;
if(rnd[x] < rnd[y]) {
pushdown(x) ;
rs[x] = merge(rs[x] , y) ;
pushup(x) ;
return x ;
} else {
pushdown(y) ;
ls[y] = merge(x , ls[y]) ;
pushup(y) ;
return y ;
}
}
void split(int cur , int k , int & x , int & y) {
if(! cur) {
x = y = 0 ;
return ;
}
pushdown(cur) ;
if(sz[ls[cur]] < k) {
split(rs[cur] , k - sz[ls[cur]] - 1 , x , y) ;
rs[cur] = 0 ;
pushup(cur) ;
x = merge(cur , x) ;
} else {
split(ls[cur] , k , x , y) ;
ls[cur] = 0 ;
pushup(cur) ;
y = merge(y , cur) ;
}
}
int newrt(int len) {
int _newrt = 0 ;
for(int i = 1 ; i <= len ; i ++) _newrt = merge(_newrt , newnode(read())) ;
return _newrt ;
}
void insert(int pos , int len) {
int x , y ;
split(rt , pos , x , y) ;
rt = merge(merge(x , newrt(len)) , y) ;
}
void remove(int l , int r) {
int x , y , z ;
split(rt , l - 1 , x , z) ;
split(z , r - l + 1 , y , z) ;
rt = merge(x , z) ;
}
void rever(int l , int r) {
int x , y , z ;
split(rt , l - 1 , x , z) ;
split(z , r - l + 1 , y , z) ;
reverse(y) ;
rt = merge(merge(x , y) , z) ;
}
void cover(int l , int r , int v) {
int x , y , z ;
split(rt , l - 1 , x , z) ;
split(z , r - l + 1 , y , z) ;
cover(y , v) ;
rt = merge(merge(x , y) , z) ;
}
int query_sum(int l , int r) {
int x , y , z ;
split(rt , l - 1 , x , z) ;
split(z , r - l + 1 , y , z) ;
int res = sum[y] ;
rt = merge(merge(x , y) , z) ;
return res ;
}
int query_point(int pos) {
int x , y , z ;
split(rt , pos , x , z) ;
split(x , pos - 1 , x , y) ;
int res = val[y] ;
rt = merge(merge(x , y) , z) ;
return res ;
}
int query_max_sum(int l , int r) {
int x , y , z ;
split(rt , l - 1 , x , z) ;
split(z , r - l + 1 , y , z) ;
int res = mx[y] ;
rt = merge(merge(x , y) , z) ;
return res ;
}
int getopt(std :: string opt) {
if(opt == "INSERT") return 1 ;
if(opt == "DELETE") return 2 ;
if(opt == "REVERSE") return 3 ;
if(opt == "MAKE-SAME") return 4 ;
if(opt == "GET-SUM") return 5 ;
if(opt == "GET") return 6 ;
if(opt == "MAX-SUM") return 7 ;
}
int main() {
srand(19260817) ;
n = read() , m = read() ;
rt = newrt(n) ;
while(m --) {
std :: string s ;
std :: cin >> s ;
int opt = getopt(s) ;
if(opt == 1) {
int pos = read() , len = read() ;
insert(pos , len) ;
}
if(opt == 2) {
int pos = read() , len = read() ;
remove(pos , pos + len - 1) ;
}
if(opt == 3) {
int pos = read() , len = read() ;
rever(pos , pos + len - 1) ;
}
if(opt == 4) {
int pos = read() , len = read() , v = read() ;
cover(pos , pos + len - 1 , v) ;
}
if(opt == 5) {
int pos = read() , len = read() ;
printf("%d\n" , query_sum(pos , pos + len - 1)) ;
}
if(opt == 6) printf("%d\n" , query_point(read())) ;
if(opt == 7) {
int pos = read() , len = read() ;
printf("%d\n" , query_max_sum(pos , pos + len - 1)) ;
}
}
return 0 ;
}
P2710 数列[fhq treap]的更多相关文章
- BZOJ 1500 [NOI2005]维修数列 FHQ Treap
终于A了这题...这题还是很好...但是我太菜...重构了三遍qwq FHQ Treap大法好!qwq...~~ Ins:直接拿输入造一棵树,把原来的树split成[1,pos],[pos+1,n], ...
- 【fhq Treap】bzoj1500(听说此题多码上几遍就能不惧任何平衡树题)
1500: [NOI2005]维修数列 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 15112 Solved: 4996[Submit][Statu ...
- fhq treap最终模板
新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...
- NOI 2002 营业额统计 (splay or fhq treap)
Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...
- 【POJ2761】【fhq treap】A Simple Problem with Integers
Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...
- 「FHQ Treap」学习笔记
话说天下大事,就像fhq treap —— 分久必合,合久必分 简单讲一讲.非旋treap主要依靠分裂和合并来实现操作.(递归,不维护fa不维护cnt) 合并的前提是两棵树的权值满足一边的最大的比另一 ...
- FHQ Treap摘要
原理 以随机数维护平衡,使树高期望为logn级别 不依靠旋转,只有两个核心操作merge(合并)和split(拆分) 因此可持久化 先介绍变量 ; int n; struct Node { int v ...
- FHQ Treap小结(神级数据结构!)
首先说一下, 这个东西可以搞一切bst,treap,splay所能搞的东西 pre 今天心血来潮, 想搞一搞平衡树, 先百度了一下平衡树,发现正宗的平衡树写法应该是在二叉查找树的基础上加什么左左左右右 ...
- 在平衡树的海洋中畅游(四)——FHQ Treap
Preface 关于那些比较基础的平衡树我想我之前已经介绍的已经挺多了. 但是像Treap,Splay这样的旋转平衡树码亮太大,而像替罪羊树这样的重量平衡树却没有什么实际意义. 然而类似于SBT,AV ...
随机推荐
- for和while——python中的循环控制语句详解
循环语句在绝大多数的语言中,都是必不可少的一种控制语句,循环语句允许我们执行一个语句或语句组多次.在python中有for循环和while循环两种,讲到这里,就不得不提到我们的迭代器对象 迭代器 迭代 ...
- [Effective Java 读书笔记] 第二章 创建和销毁对象 第二条
第二条 遇到多个构造器参数时,可以考虑用构建器 当遇到有多个构造器参数时,常见的是用重叠构造器,即: public class TestClass{ public TestClass(int para ...
- Spring中的可扩展接口
1.监听器Listener(点此连接,执行流程带源码分析及demo) 2.bean定义的后置处理器(BeanDefinitionRegistryPostProcessor)和bean工厂的后置处理器( ...
- Spring Bean几种注入方式——setter(常用),构造器,注入内部Bean,注入集合,接口...
依赖注入分为三种方式: 1.1构造器注入 构造器通过构造方法实现,构造方法有无参数都可以.在大部分情况下我们都是通过类的构造器来创建对象,Spring也可以采用反射机制通过构造器完成注入,这就是构造器 ...
- REDTEAM 指南---第四章 外部侦察
第四章 外部侦察 贡献者:Haythem Arfaoui 翻译BugMan 主动侦察 介绍 主动足迹涉及使用可以帮助您收集更多信息的工具和技术 有关目标的信息.与被动足迹不同的是,过程永远不会“触及” ...
- 广西Ukey登录需求
1.前端控制浏览器用户安装证书[1.检测,2,提示用户强制安装] JITComVCTK_S.exe 2.前端调用接口获取认证原文 3.对前端认证原文处理,提交请求到后端 摘算法处理后的认证原文 认证原 ...
- Java的七大排序
一.各个算法的时间复杂度 二,具体实现 1.直接选择排序 基本思想:在长度为n的序列中,第一次遍历找到该序列的最小值,替换掉第一个元素,接着从第二个元素开始遍历,找到剩余序列中的最小值,替换掉第二个元 ...
- Git push时不需要总输入密码
遇到问题: 最近因为换了自己的邮箱密码后,每次push的时候都需要填写密码,账号.很烦 解决方法: [戎马半生的答案] (http://www.cnblogs.com/zhaoyu1995/p/650 ...
- Linux下使用VsCode进行Qt开发环境搭建
最近在Linux上搞Qt, vim环境还用不太习惯, QtCreator之前使用时莫名其妙崩溃然后丢失代码之后就被我彻底放弃了, 于是研究了一下用VsCode进行Qt开发. 首先是系统环境和下载安装包 ...
- 二、Nginx配置实例
Nginx配置实例 一.反向代理 实例一 1.实现效果 打开浏览器,在浏览器地址栏输入地址 www.123.com ,跳转到linux系统tomcat主页面中. 2.准备工作 在linux系统中安装t ...