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

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

 #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. bzoj千题计划225:bzoj2143: 飞飞侠

    http://www.lydsy.com/JudgeOnline/problem.php?id=2143 分层图最短路 把能够弹跳的曼哈顿距离看做能量 dp[i][j][k]表示在(i,j)位置,还有 ...

  2. 第6月第17天 CGAffineTransformMake(a,b,c,d,tx,ty) 矩阵运算的原理

    1. 为了把二维图形的变化统一在一个坐标系里,引入了齐次坐标的概念,即把一个图形用一个三维矩阵表示,其中第三列总是(0,0,1),用来作为坐标系的标准.所以所有的变化都由前两列完成. 以上参数在矩阵中 ...

  3. [转]CMake cache

    CMakeCache.txt 可以将其想象成一个配置文件(在Unix环境下,我们可以认为它等价于传递给configure的参数). CMakeLists.txt 中通过 set(... CACHE . ...

  4. 云计算--MPI

    [root@localhost mpi]# mpicc -c base.c[root@localhost mpi]# mpicc -o base base.o[root@localhost mpi]# ...

  5. string替换所有指定字符串(C++)

    C++的string提供了replace方法来实现字符串的替换,但是对于将字符串中某个字符串全部替换这个功能,string并没有实现,我们今天来做的就是这件事. 首先明白一个概念,即string替换所 ...

  6. Android Camera详解

    相关的类 android.hardware.camera2 Camera SurfaceView---这个类用于向用户呈现实时相机预览. MediaRecorder---这个类用于从摄像机录制视频. ...

  7. (转)javascript方法--bind()

    地址:https://www.cnblogs.com/xxxxBW/p/4914567.html bind方法,顾名思义,就是绑定的意思,到底是怎么绑定然后怎么用呢,下面就来说说我对这个方法的理解. ...

  8. 输出联系变化的数字seq

    主要作用:输出联系变化的数字格式:Seq 分割符号 开始 间隔 结束开始默认是1,间隔默认是1,分隔符默认回车一位是结束,两位首末,三位首间隔末,没有四位,开始可以是负数主要参数:-f 指定格式打印- ...

  9. 测试开发之Django——No4.Django中前端框架的配置与添加

    我们在开发一个web项目的时候,虽然我们不是专业开发,但是我们也想要做出来一个美美的前端页面. 这种时候,百度上铺天盖地的前端框架就是我们的最好选择了. 当然,在网上直接下载的框架,我们是不能直接用的 ...

  10. java 多重继承

    接口不仅仅只是一种更纯粹形式的抽象类,它的目标比这更高,因为接口是根本没有任何具体实现的--也就是说,没有任何与接口相关的存储,因此也就无法阻止多个接口的组合, 在导出类中,不强制要求必须有一个抽象的 ...