一开始写的是暴力判断,WA30分,后来改成位运算,直接RE保灵。
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,m,q;
char s[100015][35];
struct Tree{
int l,r,ans,x,y;
}t[400114];
void upd(int p){
t[p].x = t[p*2].x|t[p*2+1].x;
t[p].y = t[p*2].y|t[p*2+1].y;
t[p].ans = (t[p*2].ans && t[p*2+1].ans)&&((t[p*2].x&t[p*2+1].x)&(t[p*2].y^t[p*2+1].y)==0);
// int x1 = t[p*2].x,x2 = t[p*2+1].x,y1 = t[p*2].y,y2 = t[p*2+1].y;
// for(int i=1;i<=n;i++){
// if((x1&(1<<i))&&(x2&(1<<i))&&(y1&(1<<i))!=(y2&(1<<i))) {
// t[p].ans = 0; break;
// }
// }
}
void build(int p,int l,int r){
t[p].l = l, t[p].r = r;
if(l==r){
t[p].ans = 1;
for(int i=1;i<=n;i++){
if(s[l][i]!='?'){
t[p].x |= 1<<i;
if(s[l][i]!='0')
t[p].y |= 1<<i;
}
}
return ;
}
int mid = (l+r) / 2;
build(p*2,l,mid); build(p*2+1,mid+1,r);
upd(p);
}
Tree ask(int p,int l,int r){
if(t[p].l>=l&&t[p].r<=r){
return t[p];
}
int mid = (t[p].l+t[p].r)/2;
Tree L,R,res;
if(l<=mid) L=ask(p*2,l,r);
if(r>mid) R=ask(p*2+1,l,r);
if(l<=mid&&r>mid){
res.x = L.x|R.x;
res.y = L.y|R.y;
res.ans = (L.ans && R.ans)&&((L.x&R.x)&(L.y^R.y)==0);
// res.ans = L.ans && R.ans;
// int x1 = L.x,x2 = R.x,y1 = L.y,y2 = R.y;
// for(int i=1;i<=n&&res.ans;i++){
// if((x1&(1<<i))&&(x2&(1<<i))&&(y1&(1<<i))!=(y2&(1<<i)))
// res.ans = 0;
// x1>>=1;x2>>=1;y1>>=1;y2>>=1;
// }
return res;
}else{
if(l<=mid) return L;
else return R;
}
}
void change(int p,int x){
if(t[p].l==x&&t[p].r==x){
t[p].ans = 1;t[p].x = t[p].y = 0;
for(int i=1;i<=n;i++){
if(s[x][i]!='?'){
t[p].x |= 1<<i;
if(s[x][i]!='0')
t[p].y |= 1<<i;
}
}
return ;
}int mid = (t[p].l+t[p].r) / 2;
if(x<=mid) change(p*2,x);
else change(p*2+1,x);
upd(p);
}
signed main(){
freopen("P5522_12.in","r",stdin);
freopen("P5522_12.out","w",stdout);
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin>>n>>m>>q;
for(int i=1;i<=m;i++)
cin>>(s[i]+1);
build(1,1,m);
int ANS = 0;
while(q--){
int op; cin>>op;
if(op == 0){
int l,r;
cin>>l>>r;
Tree g = ask(1,l,r);
if(g.ans){
int sum = 1;
for(int i=1;i<=n;i++)
if((g.x&(1<<i))==0)
sum*=2;
ANS^=sum;
}
}else{
int x;
cin>>x;
cin>>(s[x]+1);
change(1,x);
}
}
cout<<ANS;
return 0;
}