[20200724NOIP提高组模拟T2]圣章-精灵使的魔法语

题目大意:

  给你一段长度为$n$的括号序列,有以下操作:一、Change x:将x处的括号反向;二、Query x y:查询欲使[x,y]内的括号序列合法,至少要从左端右端分别添加几个括号.

solution:

  线段树板子,注意以下更新即可:

inline node update(node a,node b){node wn;wn._=a._+max(0,b._-a.__);wn.__=b.__+max(0,a.__-b._);return wn;}

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<queue>
#define R register
#define next exnttttttttt
#define debug puts("mlg")
using namespace std;
typedef int ll;
typedef long double ld;
typedef unsigned long long ull;
inline ll read();
inline void write(ll x);
inline void writesp(ll x);
inline void writeln(ll x);
ll n,m; 
bool c[200000];
struct node{
    ll _,__;
}t[800000];
inline node update(node a,node b){node wn;wn._=a._+max(0,b._-a.__);wn.__=b.__+max(0,a.__-b._);return wn;}
inline void build(ll p,ll l,ll r){
    if(l==r){
        if(c[l])t[p]._=1;            
        else t[p].__=1;
        return;
    }
    ll mid=l+r>>1;
    build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    t[p]=update(t[p<<1],t[p<<1|1]);
}
inline void change(ll p,ll l,ll r,ll goal){
    if(l==r){
        swap(t[p]._,t[p].__);return;
    }
    ll mid=l+r>>1;
    if(goal<=mid) change(p<<1,l,mid,goal);
    else change(p<<1|1,mid+1,r,goal);
    t[p]=update(t[p<<1],t[p<<1|1]);
}
inline node query(ll p,ll l,ll r,ll goalL,ll goalR){
    if(goalL<=l&&r<=goalR) return t[p];
    ll mid=l+r>>1;
    if(goalL>mid) return query(p<<1|1,mid+1,r,goalL,goalR);
    if(goalR<=mid) return query(p<<1,l,mid,goalL,goalR);
    node x=query(p<<1,l,mid,goalL,goalR),y=query(p<<1|1,mid+1,r,goalL,goalR);
    return update(x,y); 
}
int main(){
    n=read();m=read();
    for(R ll i=1;i<=n;i++){
        char wn=getchar();
        while(wn!='('&&wn!=')') wn=getchar();
        c[i]=wn==')';
    }
    build(1,1,n);
    while(m--){
        char wn=getchar();
        while(wn!='C'&&wn!='Q') wn=getchar();
        if(wn=='C'){
            ll x=read();
            change(1,1,n,x);
        }
        else{
            ll x=read(),y=read();
            node ans=query(1,1,n,x,y);
            writesp(ans._);writeln(ans.__);
        }
    }
}
inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;}
inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');}
inline void writesp(ll x){write(x);putchar(' ');}
inline void writeln(ll x){write(x);putchar('\n');}

 

posted @ 2020-07-24 15:34  月落乌啼算钱  阅读(168)  评论(0编辑  收藏  举报