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

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

 #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. ngx_lua_API 指令详解(五)coroutine.create,coroutine.resume,coroutine.yield 等集合指令介绍

    ngx_lua 模块(原理实现) 1.每个worker(工作进程)创建一个Lua VM,worker内所有协程共享VM: 2.将Nginx I/O原语封装后注入 Lua VM,允许Lua代码直接访问: ...

  2. android tools相关

    1.showin 在include 的根节点设置,可一预览效果

  3. HDU 2073 无限的路 (模拟)

    题目链接 Problem Description 甜甜从小就喜欢画图画,最近他买了一支智能画笔,由于刚刚接触,所以甜甜只会用它来画直线,于是他就在平面直角坐标系中画出如下的图形: 甜甜的好朋友蜜蜜发现 ...

  4. windows环境命令行创建虚拟环境

    1:安装virtualenv pip install virtualenv 2:创建并激活虚拟环境 #创建虚拟环境 D:\>mkdir xianmu D:\>cd xianmu D:\xi ...

  5. linux下简单的备份的脚本 2 【转】

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4577034 之前写过linux下简单的 ...

  6. 爬虫、框架scrapy

    阅读目录 一 介绍 二 安装 三 命令行工具 四 项目结构以及爬虫应用简介 五 Spiders 六 Selectors 七 Items 八 Item Pipeline 九 Dowloader Midd ...

  7. 七、vue语法补充二(动态组件 & 异步组件、访问元素 & 组件、混入)

    1..sync 修饰符 2.3.0+ 新增 vue 修饰符sync的功能是:当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定.类似于v-model的效果 例子: this.$ ...

  8. TimedSupervisorTask

    啊啊啊 UnsupportedOperationException Lists.emptyLIst() . add (String[] ) 这他妈的不行.. .2017/09/13 16:42:16. ...

  9. 洛谷P3383线性筛素数

    传送门 代码中体现在那个 $ break $ $ prime $ 数组 中的素数是递增的,当 $ i $ 能整除 $ prime[j ] $ ,那么 $ iprime[j+1] $ 这个合数肯定被 $ ...

  10. 【TensorFlow】获取object detection API训练模型的输出坐标

    如下图,谷歌开源的object detection API提供了五种网络结构的fine-tuning训练权重,方便我们针对目标检测的需求进行模型训练,本文详细介绍下导出训练模型后,如何获得目标检测框的 ...