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的考验[平衡树]的更多相关文章

  1. 洛谷 P4883 mzf的考验 解题报告

    P4883 mzf的考验 题目背景 \(mzf\)立志要成为一个豪杰,当然,他也是一个\(OIer\). 他希望自己除了会\(OI\)之外还会各种东西,比如心理学.吉他.把妹等等. 为了让自己有更大的 ...

  2. 【洛谷】P4883 mzf的考验

    [洛谷]P4883 mzf的考验 最近忽然放弃治疗开始随机跳题了 感觉还行 就是必须吸氧感觉有点糟糕... 这题翻转和求和都是平衡树基本操作,那个异或可以通过维护树中\(2\)进制下第\(2^{i}\ ...

  3. 洛谷【P4883】mzf的考验

    浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...

  4. mzf的考验

    题解: 比较水吧 显然是平衡树的操作 然后就是写写写 用对拍来查错相比之下直接样例查还是比较容易的 刚开始没有优化常数没开O2就变成暴力分了smg 开了O2就a了 代码: #include <b ...

  5. luogu4883 mzf的考验

    题目描述: luogu 题解: 当然splay. 区间翻转是基本操作. 区间异或?按套路记录区间内每一位$1$的个数,异或的时候按位取反即可. 区间查询同理. 因为要按位维护,所以复杂度多了个log. ...

  6. [BZOJ3223]Tyvj 1729 文艺平衡树

    [BZOJ3223]Tyvj 1729 文艺平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区 ...

  7. [BZOJ3224]Tyvj 1728 普通平衡树

    [BZOJ3224]Tyvj 1728 普通平衡树 试题描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个) ...

  8. BZOJ3223: Tyvj 1729 文艺平衡树 [splay]

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3595  Solved: 2029[Submit][Sta ...

  9. [普通平衡树treap]【学习笔记】

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9046  Solved: 3840[Submit][Sta ...

随机推荐

  1. HDU 1004 Let the Balloon Rise(STL初体验之map)

    Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...

  2. WebAPI 微信小程序的授权登录以及实现

    这个星期最开始 ,老大扔了2个任务过来,这个是其中之一.下面直接说步骤: 1.  查阅微信开发文档  https://developers.weixin.qq.com/miniprogram/dev/ ...

  3. Django表单Form类对空值None的替换

    最近在写项目的时候用到Form,发现这个类什么都好,就是有些空值的默认赋值真是很不合我胃口. 查阅资料.官方文档后发现并没有设置该值的方式.于是,便开始了我的踩坑之路...... 不过现在完美解决了, ...

  4. Decorator - 装饰器

    装饰器 Decorator, 先来看看对 decorator 这个名词的解释, 一个可调用的对象 A (decorator), 返回另一个可调用的对象 B, 在可调用的对象 C 的定义体之前通过语法 ...

  5. [Effective Java 读书笔记] 第三章类和接口 第十六条

    第十六条 复合优先于继承 如果不确定B和A的关系是,is-a的关系,B确实也是A,那么久不应该使用B继承A,否则会暴露实现细节, 你的实现都会限制在原始的实现上. 书中举的第一个例子,实现了一个类ex ...

  6. 15-Git使用语法

    Git命令 版本库的创建 方法一:使用git bash 1. 在当当前要加创建版本库的文件夹右键使用GitBash 创建仓库执行命令: $ git init 方法二:使用TortoiseGit 2. ...

  7. CentOS7重置密码

    #在vmlinuz段最后添加rd.break Ctrl+X启动 rd.break #在linux16/linux/linuxefi所在参数行尾添加以下内容 init=/bin/sh #此时,可使用mo ...

  8. 1213 - Fantasy of a Summation

    1213 - Fantasy of a Summation         If you think codes, eat codes then sometimes you may get stres ...

  9. 使用A线程打印1-52,B线程打印A-Z,要求按照12A34B56C....5152Z的顺序进行交替打印

    多线程同步问题,都需要用到监视器,用来监视资源是否可用.C++中使用condition_variable,Java中使用Condition来实现同步. 1. 实现思路 需要有一个全局变量控制当前该哪个 ...

  10. js 细节

    1.js中var a=s=1和var a=1,s=1的区别 function fl() { ; } function fl1() { , s = ; } 看出问题所在了吗? var q=w=1 中的s ...