反转操作 + 翻转操作 = 对称操作

因为上面三个操作都是自己的逆操作,所以我们只需要实现对称操作和反转操作,就可以搞定翻转操作.

 #include <cstdio>
#include <algorithm>
#define N 100010
using namespace std; struct Node {
int siz, val, clf[], crg[], rtag, etag;
Node *ch[], *par;
void update() {
int v;
v = (ch[]?ch[]->crg[]:) + val - (ch[]?ch[]->clf[]:);
clf[] = (ch[]?ch[]->clf[]:), crg[] = (ch[]?ch[]->crg[]:);
if( v> ) crg[]+=v;
else clf[]+=-v;
v = (ch[]?ch[]->crg[]:) + (-val) - (ch[]?ch[]->clf[]:);
clf[] = (ch[]?ch[]->clf[]:), crg[] = (ch[]?ch[]->crg[]:);
if( v> ) crg[]+=v;
else clf[]+=-v;
siz = (ch[]?ch[]->siz:) + + (ch[]?ch[]->siz:);
}
void pushdown() {
if( rtag ) {
if( ch[] ) ch[]->reverse();
if( ch[] ) ch[]->reverse();
rtag = ;
}
if( etag ) {
if( ch[] ) ch[]->exchange();
if( ch[] ) ch[]->exchange();
etag = ;
}
}
void reverse() {
swap( ch[], ch[] );
swap( clf[], crg[] );
swap( clf[], crg[] );
rtag ^= ;
}
void exchange() {
swap( clf[], clf[] );
swap( crg[], crg[] );
val = -val;
etag ^= ;
}
}pool[N], *tail=pool, *root; int n, m;
char buf[N]; Node *find( int pos ) {
Node *nd = root;
pos++;
while() {
nd->pushdown();
int lz = nd->ch[]?nd->ch[]->siz:;
if( pos<=lz ) {
nd=nd->ch[];
} else if( pos==lz+ ){
return nd;
} else {
pos -= lz+;
nd=nd->ch[];
}
}
}
void rotate( Node *nd, int d ) {
Node *p = nd->par;
Node *s = nd->ch[!d];
Node *ss = s->ch[d]; if( !p ) root=s;
else p->ch[ nd==p->ch[] ] = s;
if( s ) s->ch[d] = nd;
nd->ch[!d] = ss; nd->par = s;
s->par = p;
if( ss ) ss->par = nd; nd->update();
s->update();
}
void bigpush( Node *nd ) {
if( !nd ) return;
bigpush(nd->par);
nd->par->pushdown();
}
void splay( Node *nd, Node *top= ) {
while( nd->par!=top ) {
Node *p = nd->par;
int nl = nd==p->ch[];
if( p->par==top ) {
rotate( p, nl );
} else {
Node *pp = p->par;
int pl = p==pp->ch[];
if( nl==pl ) {
rotate( pp, pl );
rotate( p, nl );
} else {
rotate( p, nl );
rotate( pp, pl );
}
}
}
}
Node *fetch( int lf, int rg ) {
Node *nl = find(lf-);
Node *nr = find(rg+);
splay(nl);
splay(nr,nl);
return nr->ch[];
}
Node *newnode( Node *par, int v ) {
Node *nd = ++tail;
nd->par = par;
nd->ch[] = nd->ch[] = ;
nd->siz = ;
nd->val = v;
nd->clf[] = v==-;
nd->crg[] = v==;
nd->clf[] = -v==-;
nd->crg[] = -v==;
nd->rtag = nd->etag = ;
return nd;
}
Node *build( Node *par, int lf, int rg ) {
if( lf>rg ) return ;
int mid=(lf+rg)>>;
Node *nd = newnode( par, buf[mid]=='('?:- );
nd->ch[] = build( nd, lf, mid- );
nd->ch[] = build( nd, mid+, rg );
nd->update();
return nd;
}
int query( int lf, int rg ) {
Node *nd = fetch(lf,rg);
return ((nd->clf[]+)>>)+((nd->crg[]+)>>);
} int main() {
scanf( "%d%d", &n, &m );
scanf( "%s", buf+ );
buf[] = '(';
buf[n+] = ')';
root = build( , , n+ );
for( int i=,o,l,r; i<=m; i++ ) {
scanf( "%d%d%d", &o, &l, &r );
if( o== ) {
printf( "%d\n", query(l,r) );
} else if( o== ) {
fetch(l,r)->exchange();
} else {
fetch(l,r)->reverse();
}
}
}

bzoj 2209 括号序列的更多相关文章

  1. [BZOJ 4350]括号序列再战猪猪侠 题解(区间DP)

    [BZOJ 4350]括号序列再战猪猪侠 Description 括号序列与猪猪侠又大战了起来. 众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号 序列S合法,当且仅当: 1.( )是一个 ...

  2. bzoj 4244 括号序列dp

    将各种情况绕环等看作括号序列,括号内的区域上下都需要累加答案,左右也是 f[i][j] 代表 前i个车站已经处理完的有j个左括号的最小权值 我们可以发现,更新的来源来自于 i-1, 和 i 将上 描述 ...

  3. bzoj 1095 括号序列求两点距离

    大致题意: 给一棵树,每个节点最开始都是黑色,有两种操作,1.询问树中相距最远的一对黑点的距离 2.反转一个节点的颜色 一种做法: 建立出树的括号序列,类似这样: [A[B][C]],所以长度为3*n ...

  4. 【BZOJ】2209: [Jsoi2011]括号序列(splay)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2209 splay又犯逗........upd1那里的sum忘记赋值反............. 本题 ...

  5. bzoj 2209: [Jsoi2011]括号序列 splay

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 833  Solved: 392[Submit][Status ...

  6. BZOJ 2209: [Jsoi2011]括号序列 [splay 括号]

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1111  Solved: 541[Submit][Statu ...

  7. bzoj 2209 [Jsoi2011]括号序列 平衡树

    2209: [Jsoi2011]括号序列 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 1404  Solved: 699[Submit][Statu ...

  8. BZOJ.1095.[ZJOI2007]捉迷藏(线段树 括号序列)

    BZOJ 洛谷 对树DFS得到括号序列.比如这样一个括号序列:[A[B[E][F[H][I]]][C][D[G]]]. 那比如\(D,E\)间的最短距离,就是将\(D,E\)间的括号序列取出:][[] ...

  9. 【BZOJ】1095: [ZJOI2007]Hide 捉迷藏 括号序列+线段树

    [题目]BZOJ 1095 [题意]给定n个黑白点的树,初始全为黑点,Q次操作翻转一个点的颜色,或询问最远的两个黑点的距离,\(n \leq 10^5,Q \leq 5*10^5\). [算法]括号序 ...

随机推荐

  1. SQL语句(十三)多表查询

    多表查询 1. 笛卡尔乘积 简单格式 SELECT * 或字段列表 FROM 数据表列表 实例 --1. 笛卡尔乘积 (五条件的连接--很多条件无意义) Select * from Student, ...

  2. 那些年实用但被我忘掉javascript属性.onresize

    //获取屏幕宽度并动态赋值 var winWidth = 0; var winHeight = 0; function findDimensions() //函数:获取尺寸 { //获取窗口宽度 if ...

  3. Angular 下的 directive (part 2)

    ngCloak ngCloak指令被使用在,阻止angular模板从浏览器加载的时候出现闪烁的时候.使用它可以避免闪烁问题的出现.   该指令可以应用于<body>元素,但首选使用多个ng ...

  4. iOS手势UIGestureRecognizer的使用及手势冲突的解决办法【转】

    转自:iOS开发中的手势体系——UIGestureRecognizer分析及其子类的使用 关于手势的一篇很好的帖子,转载过来免得丢失.你可能最感兴趣的是手势间的互斥处理,那么就搜索 4.手势间的互斥处 ...

  5. CSS3 响应式布局: @media (min/max-width:***) @font-face

    响应式布局 responsive design @media 属性 bootstrap  css 分析: @media (min-width:768px){ body{***} } use @medi ...

  6. curl wget 不验证证书进行https请求【转】

    $ wget 'https://x.x.x.x/get_ips' --no-check-certificate $ curl 'https://x.x.x.x/get_ips' -k 转自 curl ...

  7. 树莓派编译安装opencv3 (2019.1.6更新)

    一.更新系统 sudo apt-get update sudo apt-get upgrade sudo rpi-update #重启系统 sudo reboot 二.安装依赖库及程序 sudo ap ...

  8. python基础-列表元组字典

    1.列表和元组 列表可以对数据实现最方便的存储.修改等操作 names=["Alex","tenglan","Eric","Rai ...

  9. Android 5.0 API

    Android 5.0 (LOLLIPOP) 为用户和应用开发者提供了新功能.本文旨在介绍其中最值得关注的新 API. 如果您有已发布的应用,请务必看一看 Android 5.0 行为变更,了解您的应 ...

  10. nodejs查询数据库后,获取result结果集并赋值返回

    nodejs获取了查询结果,但不能返回出去, 情形如下: var query = function (path,id,param,sqlWhere,res){ var aa = 111;var sql ...