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

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

 #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. POJ - 2240 Arbitrage(Bellman-Ford)

    https://vjudge.net/problem/POJ-2240 题意 已知n种货币,以及m种货币汇率及方式,问能否通过货币转换,使得财富增加. 分析 Bellman-Ford判断正环,注意初始 ...

  2. bzoj千题计划249:bzoj5100: [POI2018]Plan metra

    http://www.lydsy.com/JudgeOnline/problem.php?id=5100 1.找到d1[i]+dn[i] 最小的点,作为1到n链上的点 2.令链长为D,若abs(d1[ ...

  3. [转载]使用SQL Server 2008的事务日志传送功能备份数据库(logshiping)

    http://www.cnblogs.com/benbenkoala/archive/2009/03/11/1407793.html 引言:SQL Server的事务日志传送备份是仅次于镜像的高可靠性 ...

  4. J2EE完全手册(一)

    为了使开发者能尽快的开发企业级的应用程序,Sun在1999年推出一种基于J2SE(用于开发桌面应的Java标准版)的开发模型:J2EE,用于开发服务器应用程序与服务的Java企业版,他运行于J2EE服 ...

  5. SDWebImage源码阅读-第二篇

    一  SDWebImageManager的downloadImageWithURL的方法 上一篇,我们刚开了个头,分析了一下开始加载图片之前如何取消其他正在下载的任务,接着,我们回到 - (void) ...

  6. Linux - awk 文本处理工具三

    AWK 文件打印匹配 格式示例 awk '/Tom/' file # 打印匹配到得行 awk '/^Tom/{print $1}' # 匹配Tom开头的行 打印第一个字段 awk '$1 !~ /ly ...

  7. 【干货】Windows系统信息收集篇

    市场分析:计算机取证,就是应急响应.而应急响应的市场在于黑产的攻击频率.在当今的社会里,更多的人为了钱铤而走险的比比皆是,这个市场随着比特币,大数据,物联网的来临,规模将更加的庞大与有组织性.这将导致 ...

  8. python模块分析之time和datetime模块

    前言 我们使用time和datetime模块的主要目的是对时间戳.时间字符串.时间元组等时间的表述对象进行相互的转化.而我们平时编码涉及两个时间:一个是上海时间,也可以说是北京时间,一个是UTC时间, ...

  9. 使用Eclipse Memory Analyzer分析Tomcat内存溢出

    前言 在平时开发.测试过程中.甚至是生产环境中,有时会遇到OutOfMemoryError,Java堆溢出了,这表明程序有严重的问题.我们需要找造成OutOfMemoryError原因.一般有两种情况 ...

  10. 乐视max2 在开发中无法打印某些logcat 解决方案

    乐视屏蔽了打印log.d等类型logcat.解决方案:拨号键盘 *#*#76937#*#* 出现页面后选最下面那个选项就有了.