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

建\(n*2\)棵线段树,前\(n\)棵线段树维护每个串的第i位是否是0。

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

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

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

1.有1也有0,不可能,\(ans=0\)

2.只有1或0,一种情况,\(ans\)不变。

3.既没有0也没有1,两种情况\(ans*=2\)

像这样这棵线段树。

但是这样会很慢。

考虑状压。

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

把状态压缩成一个\(int\),最多30位,转换成十进制\(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]|flag[hao<<1|1][1];
}

查询:

data query(int hao,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
{
return (data){flag[hao][0],flag[hao][1]};
}
int mid=(l+r)/2;
data kkk=none;
if(L<=mid)
{
kkk=kkk+query(hao<<1,l,mid,L,R);
}
if(R>mid)
{
kkk=kkk+query(hao<<1|1,mid+1,r,L,R);
}
return kkk;
}

我们这里返回一个data的量,以便于后面计算答案。

计算答案的主程序:

    scanf("%d%d",&l,&r);
data ans=query(1,1,m,l,r);
anss=1;
for(int i=1;i<=n;i++)//只有1或0的方案数只有一种
{
if(ans.x&1&&ans.y&1)//第i位既有1又有0,不可能。
{
anss=0;
break;
}
if(!(ans.x&1)&&!(ans.y&1))//都是问号
{
anss*=2;
}
ans.x>>=1;
ans.y>>=1;
}
ansss^=anss;

更改:

void change(int hao,int l,int r,int x)
{
if(l==r)
{
flag[hao][0]=flag[hao][1]=0;//单点修改
for(int i=1;i<=n;i++)
{
if(ch[i]=='?')
{
continue;
}
flag[hao][ch[i]-'0']|=(1<<(i-1));
}
return;
}
int mid=(l+r)/2;
if(x<=mid)
{
change(hao<<1,l,mid,x);
}else{
change(hao<<1|1,mid+1,r,x);
}
flag[hao][0]=flag[hao<<1][0]|flag[hao<<1|1][0];
flag[hao][1]=flag[hao<<1][1]|flag[hao<<1|1][1];
}

最后就把这些函数结合在一起就可以了。

#include<bits/stdc++.h>
#define N 400010
using namespace std;
int flag[N<<2][2],n,m,q,op,ansss,l,r,anss;
char s[N][41],ch[41];
struct data
{
int x,y;
}none;
data operator +(data a,data b)
{
return (data){a.x|b.x,a.y|b.y};
}
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]|flag[hao<<1|1][1];
}
data query(int hao,int l,int r,int L,int R)
{
if(L<=l&&R>=r)
{
return (data){flag[hao][0],flag[hao][1]};
}
int mid=(l+r)/2;
data kkk=none;
if(L<=mid)
{
kkk=kkk+query(hao<<1,l,mid,L,R);
}
if(R>mid)
{
kkk=kkk+query(hao<<1|1,mid+1,r,L,R);
}
return kkk;
}
void change(int hao,int l,int r,int x)
{
if(l==r)
{
flag[hao][0]=flag[hao][1]=0;//单点修改
for(int i=1;i<=n;i++)
{
if(ch[i]=='?')
{
continue;
}
flag[hao][ch[i]-'0']|=(1<<(i-1));
}
return;
}
int mid=(l+r)/2;
if(x<=mid)
{
change(hao<<1,l,mid,x);
}else{
change(hao<<1|1,mid+1,r,x);
}
flag[hao][0]=flag[hao<<1][0]|flag[hao<<1|1][0];
flag[hao][1]=flag[hao<<1][1]|flag[hao<<1|1][1];
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=m;i++)
{
scanf("%s",s[i]+1);
}
build(1,1,m);
for(int i=1;i<=q;i++)
{
scanf("%d",&op);
if(op==0)
{
scanf("%d%d",&l,&r);
data ans=query(1,1,m,l,r);
anss=1;
for(int i=1;i<=n;i++)//只有1或0的方案数只有一种
{
if(ans.x&1&&ans.y&1)//第i位既有1又有0,不可能。
{
anss=0;
break;
}
if(!(ans.x&1)&&!(ans.y&1))//都是问号
{
anss*=2;
}
ans.x>>=1;
ans.y>>=1;
}
ansss^=anss;
}else{
scanf("%d%s",&l,ch+1);
change(1,1,m,l);
}
}
printf("%d\n",ansss);
return 0;
}

洛谷P5522 【[yLOI2019] 棠梨煎雪】的更多相关文章

  1. P5522 [yLOI2019] 棠梨煎雪

    updata on 2020.3.19 今天把博客从洛谷往博客园搬,图炸了 其实早就发现了,懒得管 那图其实就是一个用dev自带的调试功能调试时,RE了的报错 当时觉得很奇怪看不出是啥,现在再看已经觉 ...

  2. 【线段树】【P5522】[yLOI2019] 棠梨煎雪

    C [yLOI2019] 棠梨煎雪 Background 岁岁花藻檐下共将棠梨煎雪 自总角至你我某日辗转天边 天淡天青 宿雨沾襟 一年一会信笺却只见寥寥数言 --银临<棠梨煎雪> Desc ...

  3. 【6.24校内test】T3 棠梨煎雪

    [题目背景] 岁岁花藻檐下共将棠梨煎雪. 自总角至你我某日辗转天边. 天淡天青,宿雨沾襟. 一年一会信笺却只见寥寥数言. ——银临<棠梨煎雪> [问题描述] 扶苏正在听<棠梨煎雪&g ...

  4. 6.25考试整理:江城唱晚&&不老梦&&棠梨煎雪——题解

    按照旧例,先安利一下主要作者:一扶苏一 以及扶苏一直挂念的——银临姐姐:银临_百度百科 (滑稽) 好哒,现在步入正题: 先看第一题: 题解: 在NOIP范围内,看到“求方案数”,就说明这个题是一个计数 ...

  5. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  6. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  7. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  8. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  9. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

随机推荐

  1. 虚拟现实中的Motion Sickness晕动症问题 - VIMS

    虚拟现实(VR)中的晕动症 - VIMS 在玩VR的时候,很多玩家都遇到过发晕恶心等症状,这就是晕动症(Motion Sickness,以下或简称MS).MS并不是VR特有的问题.我们在坐船.坐车.坐 ...

  2. MySql5.5安装步骤及MySql_Front视图配置

    一.下载文件 有需要的朋友,请自行到百度云下载 链接:https://pan.baidu.com/s/13Cf1VohMz_a0czBI05UqJg 提取码:cmyq 二.安装MySql 2.1.运行 ...

  3. (八十三)c#Winform自定义控件-导航菜单(扩展)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  4. day 21

    目录 组合 封装 访问机制 property 多态 抽象类的目的 鸭子类型 组合 组合是指的是一个对象中的属性,时另一个对象. 组合的目的和继承一样,为了减少代码冗余 封装 封装指的是把一堆属性(特征 ...

  5. python编程基础之二

    交互式: 此处以windows为例:开始->运行->cmd,输入python 交互式界面 优点:即时,所见即所得 缺点:代码不可复用,根本无法进行维护 退出:exit() 代码是顺序执行: ...

  6. App上下左右滑动封装

    #coding=utf-8 from appium import webdriver from time import sleep caps = { "platformName": ...

  7. 什么是STM32的ISP?

    上一篇笔记分享了STM32的串口IAP实例:STM32串口IAP分享.其中,下载IAP程序时用ISP的方式进行下载.这里的ISP又是什么呢? ISP方式下载程序原理 ISP:In System Pro ...

  8. PhantomJS not found on PATH

    使用vue-cli创建项目后,npm init常出现以下问题:PhantomJS not found on PATH 这是因为文件phantomjs-2.1.1-windows.zip过大,网络不好容 ...

  9. DevSecOps 笔记

    什么是DevSecOps “DevSecOps”,一种全新的安全理念与模式,从DevOps的概念延伸和演变而来,其核心理念为安全是整个IT团队(包括开发.运维及安全团队)每个人的责任,需要贯穿从开发到 ...

  10. Math中ceil中为什么会有负零

    double c=Math.ceil(-0.5); double d=Math.floor(0.5); System.out.println(c); System.out.println(d); Sy ...