题链:

Splay
类似 BZOJ 2329 [HNOI2011]括号修复
只是多了一个Replace(替换)操作,
然后就要主要lazy标记之间的影响了。
1).Replace可以直接覆盖另外两个标记,
2).当已经有Replace标记,再覆盖Invert标记时,直接把Replace标记取反即可;在覆盖Swap标记时,Replace标记不变。
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#define MAXN 100500
using namespace std;
char s[10];
int N,M;
struct SPT{
int pmx[MAXN],pmn[MAXN],smx[MAXN],smn[MAXN],sum[MAXN],key[MAXN];
int ch[MAXN][2],siz[MAXN],fa[MAXN],cg[MAXN],lazy[MAXN],rt;
void Invert(int x){
sum[x]*=-1; key[x]*=-1;
pmx[x]*=-1; pmn[x]*=-1; swap(pmx[x],pmn[x]);
smx[x]*=-1; smn[x]*=-1; swap(smx[x],smn[x]);
}
void Swap(int x){
swap(pmx[x],smx[x]);
swap(pmn[x],smn[x]);
swap(ch[x][0],ch[x][1]);
}
void Replace(int x,int c){
key[x]=c; sum[x]=c*siz[x];
pmx[x]=max(sum[x],0); pmn[x]=min(sum[x],0);
smx[x]=max(sum[x],0); smn[x]=min(sum[x],0);
}
void Pushup(int x){
siz[x]=siz[ch[x][0]]+1+siz[ch[x][1]];
sum[x]=sum[ch[x][0]]+key[x]+sum[ch[x][1]];
pmx[x]=max(pmx[ch[x][0]],sum[ch[x][0]]+key[x]+pmx[ch[x][1]]);
pmn[x]=min(pmn[ch[x][0]],sum[ch[x][0]]+key[x]+pmn[ch[x][1]]);
smx[x]=max(smx[ch[x][1]],sum[ch[x][1]]+key[x]+smx[ch[x][0]]);
smn[x]=min(smn[ch[x][1]],sum[ch[x][1]]+key[x]+smn[ch[x][0]]);
}
void Pushdown(int x){
if(cg[x]!=0){
Replace(ch[x][0],cg[x]); cg[ch[x][0]]=cg[x]; lazy[ch[x][0]]=0;
Replace(ch[x][1],cg[x]); cg[ch[x][1]]=cg[x]; lazy[ch[x][1]]=0;
cg[x]=0;
}
if(lazy[x]&1){
Invert(ch[x][0]);
if(!cg[ch[x][0]]) lazy[ch[x][0]]^=1; else cg[ch[x][0]]*=-1;
Invert(ch[x][1]);
if(!cg[ch[x][1]]) lazy[ch[x][1]]^=1; else cg[ch[x][1]]*=-1;
lazy[x]^=1;
}
if(lazy[x]&2){
Swap(ch[x][0]);
if(!cg[ch[x][0]]) lazy[ch[x][0]]^=2;
Swap(ch[x][1]);
if(!cg[ch[x][1]]) lazy[ch[x][1]]^=2;
lazy[x]^=2;
}
}
void Rotate(int x,int &k){
static int y,z,l,r;
y=fa[x]; z=fa[y];
l=ch[y][0]!=x; r=l^1;
if(!z) k=x;
else ch[z][ch[z][0]!=y]=x;
fa[ch[x][r]]=y; fa[y]=x; fa[x]=z;
ch[y][l]=ch[x][r]; ch[x][r]=y;
Pushup(y);
}
void Splay(int x,int &k){
static int y,z;
while(x!=k){
y=fa[x]; z=fa[y];
if(y!=k) (ch[z][0]!=y)^(ch[y][0]!=x)?
Rotate(x,k):Rotate(y,k);
Rotate(x,k);
}
Pushup(x);
}
int find(int x,int num){
Pushdown(x);
if(num<=siz[ch[x][0]]) return find(ch[x][0],num);
else if(num==siz[ch[x][0]]+1) return x;
else return find(ch[x][1],num-siz[ch[x][0]]-1);
}
int Split(int l,int r){
static int dl,dr;
dl=find(rt,l); dr=find(rt,r+2);
Splay(dl,rt); Splay(dr,ch[dl][1]);
return ch[dr][0];
}
void Modify(int l,int r,int type){
static int p;
p=Split(l,r);
if(type==3){
Replace(p,(s[0]=='('?1:-1));
cg[p]=(s[0]=='('?1:-1); lazy[p]=0;
}
else{
if(type==1) Invert(p);
else Swap(p);
if(!cg[p]) lazy[p]^=type;
else if(type==1) cg[p]*=-1;
}
Pushup(fa[p]); Pushup(fa[fa[p]]);
}
void Build(int &x,int dad,int l,int r){
static char c;
if(l>r) return;
x=(l+r)>>1; fa[x]=dad;
Build(ch[x][0],x,l,x-1);
scanf(" %c",&c); key[x]=(c=='('?1:-1);
Build(ch[x][1],x,x+1,r);
Pushup(x);
}
void BorderBuild(){
rt=N+1;
key[N+1]=0; key[N+2]=0;
ch[N+1][1]=N+2; fa[N+2]=N+1;
Build(ch[N+2][0],N+2,1,N);
Pushup(N+2); Pushup(N+1);
}
int Query(int l,int r){
static int p,ANS,nl,nr;
p=Split(l,r);
nl=-pmn[p]; nr=smx[p];
ANS=(nl+1)/2+(nr+1)/2;
return ANS;
}
}DT;
int main(){
freopen("/home/noilinux/Documents/模块学习/2329.in","r",stdin);
freopen("/home/noilinux/Documents/模块学习/2329.out","w",stdout);
scanf("%d%d",&N,&M);
DT.BorderBuild();
for(int i=1,l,r;i<=M;i++){
scanf("%s",s); scanf("%d%d",&l,&r);
if(s[0]=='Q') printf("%d\n",DT.Query(l,r));
if(s[0]=='I') DT.Modify(l,r,1);
if(s[0]=='S') DT.Modify(l,r,2);
if(s[0]=='R') scanf("%s",s),DT.Modify(l,r,3);
}
return 0;
}

  

●BZOJ 2329 [HNOI2011]括号修复.cpp的更多相关文章

  1. BZOJ 2329: [HNOI2011]括号修复( splay )

    把括号序列后一定是))))((((这种形式的..所以维护一个最大前缀和l, 最大后缀和r就可以了..答案就是(l+1)/2+(r+1)/2...用splay维护,O(NlogN). 其实还是挺好写的, ...

  2. BZOJ 2329: [HNOI2011]括号修复 [splay 括号]

    题目描述 一个合法的括号序列是这样定义的: 空串是合法的. 如果字符串 S 是合法的,则(S)也是合法的. 如果字符串 A 和 B 是合法的,则 AB 也是合法的. 现在给你一个长度为 N 的由‘(' ...

  3. 【BZOJ】2329: [HNOI2011]括号修复(splay+特殊的技巧)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2329 和前一题一样,不就多了个replace操作吗.好,就打一下. 然后交上去wa了........ ...

  4. 2329: [HNOI2011]括号修复 - BZOJ

    恶心的splay,打标记的时候还有冲突,要特别小心 上次写完了,查了半天没查出错来,于是放弃 今天对着标程打代码,终于抄完了,我已经不想再写了 const maxn=; type node=recor ...

  5. 2329: [HNOI2011]括号修复

    传送魔法 一开始以为可以直接线段树的,好像还是不行……还是得用Spaly,然后就没啥了. #include<cstdio> #include<algorithm> #defin ...

  6. bzoj千题计划222:bzoj2329: [HNOI2011]括号修复(fhq treap)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2329 需要改变的括号序列一定长这样 :)))((( 最少改变次数= 多余的‘)’/2 [上取整] + ...

  7. 【BZOJ2329/2209】[HNOI2011]括号修复/[Jsoi2011]括号序列 Splay

    [BZOJ2329/2209][HNOI2011]括号修复/[Jsoi2011]括号序列 题解:我们的Splay每个节点维护如下东西:左边有多少多余的右括号,右边有多少多余的左括号,同时为了反转操作, ...

  8. BZOJ 2329/2209 [HNOI2011]括号修复 (splay)

    题目大意: 让你维护一个括号序列,支持 1.区间修改为同一种括号 2.区间内所有括号都反转 3.翻转整个区间,括号的方向不变 4.查询把某段区间变为合法的括号序列,至少需要修改多少次括号 给跪了,足足 ...

  9. BZOJ2329 [HNOI2011]括号修复

    把左括号看做$1$,右括号看做$-1$,于是查询操作等于查询一个区间左边右边最大(最小)子段和 支持区间翻转,反转,覆盖操作...注意如果有覆盖操作,之前的操作全部作废了...于是在下传标记的时候要最 ...

随机推荐

  1. Scapy实现SYN泛洪攻击

    一.实验说明 1.实验介绍 本次实验将使用python3版本的Scapy--Scapy3k来实现一个简单的DDos,本次实验分为两节,本节将学习如何使用Scapy3k来实现SYN泛洪攻击. 2.知识点 ...

  2. mahony互补滤波器C编程

    //gx...分别为重力加速度在三个轴向的分力 由加速度计测得 //ax...分别为角速度在三个轴向的角速度 由陀螺仪测得 //最后得到最终滤波完毕的x.y.z方向的角度值(°) void IMUup ...

  3. python的Virtualenv

    Virtualenv 虚拟的 Python 环境(简称 venv) 是一个能帮助你在本地目录安装不同版本的 Python 模块的 Python 环境,你可以不再需要在你系统中安装所有东西就能开发并测试 ...

  4. Django 个性化管理员站点

    from django.contrib import admin # Register your models here. from .models import Moment class Momen ...

  5. Struts2之配置文件中Action的详细配置(续)

    承接上一篇 4.处理结果的配置 Action类的实例对象调用某个方法,处理完用户请求之后,将返回一个逻辑视图名的字符串.核心Filter收到返回的逻辑视图名字符串,根据struts.xml中的逻辑视图 ...

  6. ASP.NET MVC编程——单元测试

    1自动化测试基本概念 自动化测试分为:单元测试,集成测试,验收测试. 单元测试 检验被测单元的功能,被测单元一般为低级别的组件,如一个类或类方法. 单元测试要满足四个条件:自治的,可重复的,独立的,快 ...

  7. socket , 套接口还是套接字,傻傻分不清楚

    socket 做网络通信的朋友大都对socket这个词不会感到陌生,但是它的中文翻译是叫套接口还是套接字呢,未必大多数朋友能够分清,今天我们就来聊聊socket的中文名称. socket一词的起源 在 ...

  8. Python爬虫基本原理

    爬虫基本原理 1. 什么是爬虫 请求网站并提取数据的自动化程序. 2. 爬虫基本流程 发起请求 通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers等信息,等待 ...

  9. Python内置函数(34)——map

    英文文档: map(function, iterable, ...) Return an iterator that applies function to every item of iterabl ...

  10. gogs详细配置

    sudo apt-get update sudo apt-get upgrade sudo adduser git //创建用户  密码 ******* su git//切换到git用户 cd ~   ...