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

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

 #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. Kafka 0.8 Consumer设计解析

    摘要 本文主要介绍了Kafka High Level Consumer,Consumer Group,Consumer Rebalance,Low Level Consumer实现的语义,以及适用场景 ...

  2. MySql数据库表的查询操作

    http://www.cnblogs.com/whgk/p/6149009.html 优化:http://www.ihref.com/read-16422.html MYSQL常用的几种连接查询方法

  3. html文件中jquery与velocity变量中的$冲突的解决方法

    1.使用jQuery代替$. 如:jQuery.ajax(); 缺点:不适合扩展,一旦替换成第三方库时,那就麻烦大发 2.使用jQuery.noConflict. 如:var j = jQuery.n ...

  4. [转载]Brackets - 强大免费的开源跨平台Web前端开发工具IDE (HTML/CSS/Javascript代码编辑器)

    http://brackets.io/ Brackets 是一个免费.开源且跨平台的 HTML/CSS/JavaScript 前端 WEB 集成开发环境 (IDE工具).该项目由 Adobe 创建和维 ...

  5. OnContextMenu事件(转)

    用oncontextmenu事件单禁用右键菜单 一个页面中,BODY中用oncontextmenu='return false'来取消鼠标右键:在JS中设置oncontextmenu='return ...

  6. VirtualBox中CentOS遇到的问题

    centos7 安装步骤 https://www.cnblogs.com/hihtml5/p/8217062.html 静态ip设置 TYPE="Ethernet" PROXY_M ...

  7. j2ee组件简介

  8. if语句引起的bug

    最近维护高手留下的api项目,客户端反馈一个bug过来,然后查找到可能出错的代码位置,是一个if语句,乍一看好像没什么问题,代码如下: if (company.UserId != userId || ...

  9. Linux 内核中断内幕【转】

    转自:http://www.ibm.com/developerworks/cn/linux/l-cn-linuxkernelint/ 本文对中断系统进行了全面的分析与探讨,主要包括中断控制器.中断分类 ...

  10. mac 安装gevent报错

    运行pip install gevent报错 错误信息如下 xcrun: error: invalid active developer path (/Library/Developer/Comman ...