实际上就是个傻逼线段树,但是我头一次注意到读入优化会吃掉后面一个字符,结果读入区间的右括号就被读入优化吃掉了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;
}