日常训练 Idiot 的集合

实际上就是个傻逼线段树,但是我头一次注意到读入优化会吃掉后面一个字符,结果读入区间的右括号就被读入优化吃掉了QAQ
还有就是忘记合并子树信息,以后update一定要专门写一个函数。

#include<bits/stdc++.h>
const int N = 2e6 + 50;
int n,m,cnt,l,r,sum[N],col[N],lc[N],rc[N];
bool res[N];
char op[5],L,R,c;
template <typename T> void read(T &x){
    x = 0; c = getchar();
    for (; !isdigit(c); c=getchar());
    for (; isdigit(c); c=getchar()) x = x * 10 + c - '0';
}
void build(int i, int l, int r){
    sum[i] = r - l + 1;
    col[i] = 2; res[i] = 0;
    if (l == r) return;
    build(lc[i] = ++cnt,l,(l+r)>>1);
    build(rc[i] = ++cnt,((l+r)>>1)+1,r);
}
void chg(int i, int l, int r, int _l, int _r, int c);
void rev(int i, int l, int r, int _l, int _r);
void push(int i, int l, int r){
    if (col[i] < 2){
        chg(lc[i],l,(l+r)>>1,l,(l+r)>>1,col[i]);
        chg(rc[i],((l+r)>>1)+1,r,((l+r)>>1)+1,r,col[i]);
        col[i] = 2;
    }
    if (res[i]){
        rev(lc[i],l,(l+r)>>1,l,(l+r)>>1);
        rev(rc[i],((l+r)>>1)+1,r,((l+r)>>1)+1,r);
        res[i] = 0;
    }
}
void chg(int i, int l, int r, int _l, int _r, int c){
    if (l > _r || r < _l || l > r) return;
    if (l >= _l && r <= _r){
        res[i] = 0;
        if (c) sum[i] = r - l + 1; else sum[i] = 0;
        col[i] = c;
        return;
    }
    push(i,l,r);
    chg(lc[i],l,(l+r)>>1,_l,_r,c);
    chg(rc[i],((l+r)>>1)+1,r,_l,_r,c);
    sum[i] = sum[lc[i]] + sum[rc[i]];
}
void rev(int i, int l, int r, int _l, int _r){
    if (l > _r || r < _l) return;
    if (l >= _l && r <= _r){
        sum[i] = r - l + 1 - sum[i];
        if (col[i] < 2)
            col[i] = 1 - col[i];
        else
            res[i] = !res[i];
        return;
    }
    push(i,l,r);
    rev(lc[i],l,(l+r)>>1,_l,_r);
    rev(rc[i],((l+r)>>1)+1,r,_l,_r);
    sum[i] = sum[lc[i]] + sum[rc[i]];
}
int qry(int i, int l, int r, int _l, int _r){
    if (l > _r || r < _l) return 0;
    if (l >= _l && r <= _r) return sum[i] > 0;
    push(i,l,r);
    return qry(lc[i],l,(l+r)>>1,_l,_r) || qry(rc[i],((l+r)>>1)+1,r,_l,_r);
}
int main(){
    read(n);read(m);
    n = n * 2 + 1; cnt=1;
    build(1,1,n);
    while (m--){
        scanf("%s %c",op,&L);
        read(l);read(r);
        l = l * 2 + 1 + (L == '(');
        r = r * 2 + (c == ']');
        if (op[0] == '&') chg(1,1,n,1,l-1,0), chg(1,1,n,r+1,n,0);
        if (op[0] == '|') chg(1,1,n,l,r,1);
        if (op[0] == '-') chg(1,1,n,l,r,0);
        if (op[0] == '!') rev(1,1,n,l,r);
        if (op[0] == '^') rev(1,1,n,l,r);
        if (op[0] == '?') printf("%d",qry(1,1,n,l,r));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值