洛谷P5522 【[yLOI2019] 棠梨煎雪】(状压DP,线段树)

区间操作考虑用线段树维护。

n ∗ 2 n*2 n2棵线段树,前 n n n棵线段树维护每个串的第i位是否是0。

n n n棵线段树维护每个串的第i位是否是1。

如果是问号的话,直接跳过就好(通过1和0能看出是否是问号)。

然后分三种情况统计答案:

1.有1也有0,不可能, a n s = 0 ans=0 ans=0

2.只有1或0,一种情况, a n s ans ans不变。

3.既没有0也没有1,两种情况 a n s ∗ = 2 ans*=2 ans=2

像这样这棵线段树。

但是这样会很慢。

考虑状压。

这样只用开两棵线段树,一个存零,一个存一。

把状态压缩成一个 i n t int int,最多30位,转换成十进制 i n t int int能存下。

然后的建树、查询、更改操作其实就是类似一个模板。

建树:

void build(int hao,int l,int r)
{
   
	if(l==r)
	{
   
		for(int i=1;i<=n;i++)
		{
   
			if(s[l][i]=='?')//问号跳过
			{
   
				continue;
			}
			flag[hao][s[l][i]-'0']|=(1<<(i-1));//状压
		}
		return;
	}
	int mid=(l+r)/2;
	build(hao<<1,l,mid);
	build(hao<<1|1,mid+1,r);
        flag[hao][0]=flag[hao<<1][0]|flag[hao<<1|1][0];
	flag[hao][1]=flag[hao<<1][1
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值