P4883 mzf的考验[平衡树]
维护一种数据结构 支持区间翻转 区间异或 区间求和…
显然 fhq treap
区间异或显然是拆位 然后复杂度*20
第一次先遍历一下整棵树 pushup 一下 就可以了不需要特意的用一个栈来pushup
注意下传懒标记,记得开 long long 就可以了 没了
#include <bits/stdc++.h>
using namespace std ;
#define ls(x) t[x].ch[0]
#define rs(x) t[x].ch[1]
int read() {
int x = 0 ; char c = getchar() ;
while(c < '0' || c > '9') c = getchar() ;
while(c >= '0' && c <= '9') { x = (x << 1) + (x << 3) + (c & 15) ; c = getchar() ; }
return x ;
}
#define int long long
void print(int x) {
static char st[20] ; int stp = 0 ;
if(! x) { putchar(48) ; }
while(x) { st[++ stp] = x % 10 ^ 48 ; x /= 10 ; }
while(stp) { putchar(st[stp --]) ; }
putchar('\n') ;
}
const int MAXN = 1e5 + 10 ;
struct Node { int val , rnd , sz , rev , tag , sum , ch[2] , bit[22] ; } ;
Node t[MAXN] ;
int n , m , rt = 0 , cnt = 0 ;
void pushup(int o) {
t[o].sz = t[ls(o)].sz + t[rs(o)].sz + 1 ; t[o].sum = t[ls(o)].sum + t[rs(o)].sum + t[o].val ;
for(int i = 0 ; i <= 20 ; i ++) t[o].bit[i] = t[ls(o)].bit[i] + t[rs(o)].bit[i] + ((t[o].val >> i) & 1) ;
}
void swap(int & x , int & y) { x ^= y ^= x ^= y ; }
void pushdown(int o) {
if(t[o].rev) { swap(ls(o) , rs(o)) ; if(ls(o)) t[ls(o)].rev ^= 1 ; if(rs(o)) t[rs(o)].rev ^= 1 ; t[o].rev = 0 ; }
if(t[o].tag) {
if(ls(o)) {
t[ls(o)].tag ^= t[o].tag ; t[ls(o)].sum = 0 ; t[ls(o)].val ^= t[o].tag ;
for(int i = 0 ; i <= 20 ; i ++){
if((t[o].tag >> i) & 1) t[ls(o)].bit[i] = t[ls(o)].sz - t[ls(o)].bit[i] ;
t[ls(o)].sum += t[ls(o)].bit[i] << i ;
}
}
if(rs(o)) {
t[rs(o)].tag ^= t[o].tag ; t[rs(o)].sum = 0 ; t[rs(o)].val ^= t[o].tag ;
for(int i = 0 ; i <= 20 ; i ++) {
if((t[o].tag >> i) & 1) t[rs(o)].bit[i] = t[rs(o)].sz - t[rs(o)].bit[i] ;
t[rs(o)].sum += t[rs(o)].bit[i] << i ;
}
}
t[o].tag = 0 ;
}
}
int merge(int u , int v) {
if(! u || ! v) return u | v ;
if(t[u].rnd < t[v].rnd) { pushdown(u) ; rs(u) = merge(rs(u) , v) ; pushup(u) ; return u ; }
else { pushdown(v) ; ls(v) = merge(u , ls(v)) ; pushup(v) ; return v ; }
}
void split(int cur , int k , int & u , int & v) {
if(! cur) { u = v = 0 ; return ; }
pushdown(cur) ;
if(k > t[ls(cur)].sz) { u = cur ; split(rs(u) , k - t[ls(u)].sz - 1 , rs(u) , v) ; }
else { v = cur ; split(ls(v) , k , u , ls(v)) ; }
pushup(cur) ;
}
void Reverse(int l , int r) {
int x , y , z ;
split(rt , r , x , z) ; split(x , l - 1 , x , y) ;
t[y].rev ^= 1 ; rt = merge(merge(x , y) , z) ;
}
void Modify(int l , int r , int val) {
int x , y , z ;
split(rt , r , x , z) ; split(x , l - 1 , x , y) ;
t[y].tag ^= val ; t[y].sum = 0 ; t[y].val ^= val ;
for(int i = 0 ; i <= 20 ; i ++){
if((val >> i) & 1) t[y].bit[i] = t[y].sz - t[y].bit[i] ;
t[y].sum += t[y].bit[i] << i ;
}
rt = merge(merge(x , y) , z) ;
}
int Query(int l , int r) {
int x , y , z ;
split(rt , r , x , z) ; split(x , l - 1 , x , y) ;
int res = t[y].sum ; rt = merge(merge(x , y) , z) ;
return res ;
}
int NewNode(int val) {
++ cnt ;
t[cnt].ch[0] = t[cnt].ch[1] = 0 ; t[cnt].val = val ; t[cnt].rnd = rand() ; t[cnt].sz = 1 ;
t[cnt].rev = t[cnt].tag = t[cnt].sum = 0 ;
return cnt ;
}
void Insert(int val) { rt = merge(rt , NewNode(val)) ; }
void build(int x) { if(ls(x)) build(ls(x)) ; if(rs(x)) build(rs(x)) ; pushup(x) ; }
signed main() {
srand(19260817) ;
n = read() ; m = read() ;
for(int i = 1 ; i <= n ; i ++) Insert(read()) ;
build(rt) ;
while(m --) {
int opt = read() ;
if(opt == 1) { int l = read() , r = read() ; Reverse(l , r) ; }
if(opt == 2) { int l = read() , r = read() , val = read() ; Modify(l , r , val) ; }
if(opt == 3) { int l = read() , r = read() ; print(Query(l , r)) ; }
}
return 0 ;
}
P4883 mzf的考验[平衡树]的更多相关文章
- 洛谷 P4883 mzf的考验 解题报告
P4883 mzf的考验 题目背景 \(mzf\)立志要成为一个豪杰,当然,他也是一个\(OIer\). 他希望自己除了会\(OI\)之外还会各种东西,比如心理学.吉他.把妹等等. 为了让自己有更大的 ...
- 【洛谷】P4883 mzf的考验
[洛谷]P4883 mzf的考验 最近忽然放弃治疗开始随机跳题了 感觉还行 就是必须吸氧感觉有点糟糕... 这题翻转和求和都是平衡树基本操作,那个异或可以通过维护树中\(2\)进制下第\(2^{i}\ ...
- 洛谷【P4883】mzf的考验
浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...
- mzf的考验
题解: 比较水吧 显然是平衡树的操作 然后就是写写写 用对拍来查错相比之下直接样例查还是比较容易的 刚开始没有优化常数没开O2就变成暴力分了smg 开了O2就a了 代码: #include <b ...
- luogu4883 mzf的考验
题目描述: luogu 题解: 当然splay. 区间翻转是基本操作. 区间异或?按套路记录区间内每一位$1$的个数,异或的时候按位取反即可. 区间查询同理. 因为要按位维护,所以复杂度多了个log. ...
- [BZOJ3223]Tyvj 1729 文艺平衡树
[BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...
- [BZOJ3224]Tyvj 1728 普通平衡树
[BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...
- BZOJ3223: Tyvj 1729 文艺平衡树 [splay]
3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3595 Solved: 2029[Submit][Sta ...
- [普通平衡树treap]【学习笔记】
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9046 Solved: 3840[Submit][Sta ...
随机推荐
- git push 的解决方案
如果输入$ git push origin master 提示出错信息: 或者 失败的原因:不能 push 远端仓库 原因分析:由于你当前分支落后与远程端对应分支,所以无法更新: 解决方案:使用 gi ...
- 《C# 爬虫 破境之道》:第二境 爬虫应用 — 第七节:并发控制与策略
我们在第五节中提到一个问题,任务队列增长速度太快,与之对应的采集.分析.处理速度远远跟不上,造成内存快速增长,带宽占用过高,CPU使用率过高,这样是极度有害系统健康的. 我们在开发采集程序的时候,总是 ...
- 小白学 Python 数据分析(6):Pandas (五)基础操作(2)数据选择
人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...
- centos 7安装reids
一.reids下载 下载地址: https://redis.io/ 二.解压安装 ① 解压:tar -zxvf redis-5.0.5.tar.gz ② 安装环境:yum install gcc-c ...
- react-native当使用antd-mobile出现View config not found for name div
1.npm uninstall antd-mobile 2.npm uninstall react 3.npm uninstall react-native 4.npm i xx@指定版本
- qt creator源码全方面分析(2-0)
目录 Extending Qt Creator Manual 生成领域特定的代码和模板 代码片段 文件和项目模板 自定义向导 支持其他文件类型 MIME类型 高亮和缩进 自定义文本编辑器 其他自定义编 ...
- 忘记centos的root用户密码怎么办?
1 重置centos7管理员密码 1.1 重置centos7管理员密码的几个步骤 1)重启服务器后,在grub菜单界面,根据界面显示的提示信息,按 e 进入编辑模式.注意:是否开启selinux,重置 ...
- bootstrap组件---进度条
<div class="progress"> <div class="progress-bar progress-bar-success" r ...
- pip 安装源-Python学习
1.国内常用的安装源 -- 豆瓣:https://pypi.douban.com/simple -- 阿里:https://mirrors.aliyun.com/pypi/simple --中国科技大 ...
- Linux 内核参数管理
Linux 内核有很多可以定制化的参数 -- 内核参数 ( kernel parameters ), 斟酌设置内核参数对 系统调优 意义重大. 内核参数 涵盖内核的方方面面,包括 网络 ( net ) ...