「洛谷P5522」棠梨煎雪

image
image
image
\(link\)

分析:

\(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;
}
posted @ 2022-01-20 12:08  EschatonRin  阅读(9)  评论(0)    收藏  举报