「洛谷P5522」棠梨煎雪
分析:
\(n\)只有\(30\) 考虑状压线段树
维护两个值 \(k\) 和 \(val\) 分别表示该位是否确定和该位的值
有 \('?'\) 也就是不确定的 都将该位的值设为 \(0\)
关于合并\(:\)
注意当 \(Child_{left}.k=1\)且\(Child_{right}.k=1\) 说明这一位确定 此时若\(Child_{left}.val!=Child_{right}.val\) 则冲突就无解了
左右的 \(k\) 有一边确定 则这一位的 \(k\) 也确定了 \(val\) 也同理
CODE:
点击查看代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m,T,check[N],val[N],ans;
struct SegmentTree{
int l,r,k,val;
bool solve;
}a[N<<2];
char s[35];
void up(int x)
{
a[x].k=a[x<<1].k|a[x<<1|1].k;
a[x].val=a[x<<1].val|a[x<<1|1].val;
if((a[x<<1].k&a[x<<1|1].k)&(a[x<<1].val^a[x<<1|1].val))
a[x].solve=0;
else if((!a[x<<1].solve)||(!a[x<<1|1].solve))
a[x].solve=0;
else a[x].solve=1;
}
void build(int x,int l,int r)
{
a[x].l=l;a[x].r=r;
if(l==r)
{
a[x].k=check[l];
a[x].val=val[l];
a[x].solve=1;
return;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
up(x);
}
SegmentTree query(int x,int L,int R)
{
SegmentTree res;
if(L<=a[x].l&&a[x].r<=R)
return a[x];
int mid=(a[x].l+a[x].r)>>1;
if(L<=mid&&mid<R)
{
SegmentTree l=query(x<<1,L,R);
SegmentTree r=query(x<<1|1,L,R);
res.k=l.k|r.k;
res.val=l.val|r.val;
if((l.k&r.k)&(l.val^r.val))
res.solve=0;
else if((!l.solve)||(!r.solve))
res.solve=0;
else res.solve=1;
return res;
}
if(L<=mid) return query(x<<1,L,R);
if(mid<R) return query(x<<1|1,L,R);
}
void update(int x,int p,int k,int val)
{
if(a[x].l==a[x].r)
{
a[x].k=k;
a[x].val=val;
a[x].solve=1;
return;
}
int mid=(a[x].l+a[x].r)>>1;
if(p<=mid) update(x<<1,p,k,val);
else update(x<<1|1,p,k,val);
up(x);
}
int main(){
scanf("%d%d%d",&n,&m,&T);
for(int i=1;i<=m;i++)
{
scanf("%s",s+1);
int k=0,value=0;
for(int j=1;j<=n;j++)
{
k<<=1;value<<=1;
if(s[j]>='0'&&s[j]<='9') k|=1,value|=s[j]-'0';
else k|=0,value|=0;
}
check[i]=k;
val[i]=value;
}
build(1,1,m);
while(T--)
{
int op;
scanf("%d",&op);
if(op==0)
{
int l,r,p=1;
scanf("%d%d",&l,&r);
SegmentTree x=query(1,l,r);
if(!x.solve)
{
ans^=0;
continue;
}
for(int i=1;i<=n;i++)
{
if(!(x.k&1)) p<<=1;
x.k>>=1;
}
ans^=p;
}
if(op==1)
{
int p;
scanf("%d%s",&p,s+1);
int k=0,value=0;
for(int i=1;i<=n;i++)
{
k<<=1;value<<=1;
if(s[i]>='0'&&s[i]<='9') k|=1,value|=s[i]-'0';
else k|=0,value|=0;
}
update(1,p,k,value);
}
}
printf("%d",ans);
return 0;
}




浙公网安备 33010602011771号