P5522 [yLOI2019] 棠梨煎雪
updata on 2020.3.19
今天把博客从洛谷往博客园搬,图炸了
其实早就发现了,懒得管
那图其实就是一个用dev自带的调试功能调试时,RE了的报错
当时觉得很奇怪看不出是啥,现在再看已经觉得不稀罕了RE越来越多?
所以图就不再放了
P5522 [yLOI2019] 棠梨煎雪
整理博客的时候改了一下分类标签,重新审一下
线段树+每次pushup暴力比较
先说说我在比赛中打这道题的虐心经历吧。。。:
先是指针线段树的root在地址数组里占了第一位,
但tot却初始化为0.....
这就导致了单步调试时出现了让蒟蒻不知所措的奇怪报错:
就是这,图炸了

解决后,却发现询问中n和m居然用混了......
导致比赛中这题只得了5分
所以,以我的经历提醒大家:注意变量名!注意变量名!注意变量名!(可能也只有我会把变量搞混吧。。。
----------------------------------------------手动正文分割线-----------------------------------------------
思路:
区间查询,单点修改,所以,你想到了什么?
没错,就是线段树!
我们用一个res结构体存ans和x数组:
ans表示当前l~r有几种可能的情况,如果为0就是发生了冲突,x表示可以确定的(当然我是用3表示“?”)
很显然,因为每个"?"都可以填0或1,所以对于又n个?的数列,他的可能情况数量就是 \(2^n\)
struct res{
LL ans;
int x[35]
};
再想想怎么build?
每次当lr(也就是到了叶节点),就扫一遍对应的数组,将其转存到对应的x里,如果出现3(也就是“?”),就\(ans\times 2\),当然ans要初始化为1(各位大佬应该不用我提醒。。。
当然修改和这个也差不多
那怎么将两个儿子信息合并到父节点?
我用了一个以res为返回类型的cmp函数:
如果左右有任意一个儿子ans0(有冲突),那么父节点的ans直接为0
然后逐一暴力比对,对于每两个对应的原素:
- 相等且不等于3:ret.x[i]=aa.x[i],ans不变
- 相等且等于3:ret.x[i]=3,\(ans \times 2\)
- 不等且都不为3:说明发生了冲突,ans=0,返回
- 不等且一个为3:ret.x[i]赋值为不等于3的那个,ans不变
下面是这个函数的代码:(上面讲的应该比较清晰了,就不再注释了)
inline res cmp(res aa,res bb){
res ret;
if(aa.ans==0||bb.ans==0){
ret.ans=0;
return ret;
}
ret.ans=1;
for(R int i=1;i<=n;i++){
if(aa.x[i]==bb.x[i]){
if(aa.x[i]!=3){
ret.x[i]=aa.x[i];
continue;
}
else{
ret.x[i]=3;
ret.ans*=2;
}
}
if(aa.x[i]!=3&&bb.x[i]!=3){
ret.ans=0;
return ret;
}
if(aa.x[i]==3)
ret.x[i]=bb.x[i];
else ret.x[i]=aa.x[i];
}
return ret;
}
然后再把这给函数返回的ret赋值给当前节点就行了
tree->o=cmp(tree->ls->o,tree->rs->o);
最后一个问题,怎么查询?
我们还是要用到cmp函数,比较从两个子节点返回的信息,然后返回到上层
好了,应该就这些了吧,放上代码(我知道这才是泥萌想要的
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#define R register
#define EN printf("\n")
#define LL long long
inline int read(){
int x=0,y=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-') y=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+(c^48);c=getchar();}
return x*y;
}
int n,m,q;
struct res{
LL ans;
int x[35];
};
struct tr{
tr *ls,*rs;
res o;
}dizhi[200017],*root=&dizhi[0];
int tot;
int now[35],a[100017][35];
inline res cmp(res aa,res bb){
res ret;
if(aa.ans==0||bb.ans==0){
ret.ans=0;
return ret;
}
ret.ans=1;
for(R int i=1;i<=n;i++){
if(aa.x[i]==bb.x[i]){
if(aa.x[i]!=3){
ret.x[i]=aa.x[i];
continue;
}
else{
ret.x[i]=3;
ret.ans*=2;
}
}
if(aa.x[i]!=3&&bb.x[i]!=3){
ret.ans=0;
return ret;
}
if(aa.x[i]==3)
ret.x[i]=bb.x[i];
else ret.x[i]=aa.x[i];
}
return ret;
}
void build(tr *tree,int l,int r){
if(l==r){
tree->o.ans=1;
for(R int i=1;i<=n;i++){
tree->o.x[i]=a[l][i];
if(a[l][i]==3) tree->o.ans*=2;
}
return;
}
int mid=(l+r)>>1;
tree->ls=&dizhi[++tot];
tree->rs=&dizhi[++tot];
build(tree->ls,l,mid);
build(tree->rs,mid+1,r);
tree->o=cmp(tree->ls->o,tree->rs->o);
}
void change(tr *tree,int l,int r,int k){
if(l==r){
tree->o.ans=1;
for(R int i=1;i<=n;i++){
tree->o.x[i]=now[i];
tree->o.ans*=2;
}
return;
}
int mid=(l+r)>>1;
if(k<=mid) change(tree->ls,l,mid,k);
else change(tree->rs,mid+1,r,k);
tree->o=cmp(tree->ls->o,tree->rs->o);
}
res qq(tr *tree,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) {
return tree->o;
}
int mid=(l+r)>>1;
res aa,bb;
aa.ans=bb.ans=-1;
if(ql<=mid) aa=qq(tree->ls,l,mid,ql,qr);
if(qr>mid) bb=qq(tree->rs,mid+1,r,ql,qr);
if(aa.ans==-1) return bb;
if(bb.ans==-1) return aa;
return cmp(aa,bb);
}
int main(){
char c;
int anss=0;
n=read();m=read();q=read();
for(R int i=1;i<=m;i++){
c=getchar();
while(c==' '||c=='\n') c=getchar();
for(R int j=1;j<=n;j++){
if(c=='?') a[i][j]=3;
else a[i][j]=c-48;
c=getchar();
}
}
build(root,1,m);
for(R int i=1;i<=q;i++){
int op=read();
if(op){
op=read();
c=getchar();
while(c==' ') c=getchar();
for(R int j=1;j<=n;j++){
if(c=='?') now[j]=3;
else now[j]=c-48;
c=getchar();
}
change(root,1,m,op);
}
else{
int l=read(),r=read();
anss^=qq(root,1,m,l,r).ans;
}
}
printf("%d",anss^0);
return 0;
}
这是身为蒟蒻的我写的第一篇题解,有错误或没讲明白的地方, 欢迎各位大佬私信
P5522 [yLOI2019] 棠梨煎雪的更多相关文章
- 【线段树】【P5522】[yLOI2019] 棠梨煎雪
C [yLOI2019] 棠梨煎雪 Background 岁岁花藻檐下共将棠梨煎雪 自总角至你我某日辗转天边 天淡天青 宿雨沾襟 一年一会信笺却只见寥寥数言 --银临<棠梨煎雪> Desc ...
- 洛谷P5522 【[yLOI2019] 棠梨煎雪】
区间操作考虑用线段树维护. 建\(n*2\)棵线段树,前\(n\)棵线段树维护每个串的第i位是否是0. 后\(n\)棵线段树维护每个串的第i位是否是1. 如果是问号的话,直接跳过就好(通过1和0能看出 ...
- 【6.24校内test】T3 棠梨煎雪
[题目背景] 岁岁花藻檐下共将棠梨煎雪. 自总角至你我某日辗转天边. 天淡天青,宿雨沾襟. 一年一会信笺却只见寥寥数言. ——银临<棠梨煎雪> [问题描述] 扶苏正在听<棠梨煎雪&g ...
- 6.25考试整理:江城唱晚&&不老梦&&棠梨煎雪——题解
按照旧例,先安利一下主要作者:一扶苏一 以及扶苏一直挂念的——银临姐姐:银临_百度百科 (滑稽) 好哒,现在步入正题: 先看第一题: 题解: 在NOIP范围内,看到“求方案数”,就说明这个题是一个计数 ...
- 校内测之zay与银临 (day2)(只有T1)
一些与题目无关的碎碎念 推出式子来一定要化简!!!freopen不要写错!!!特判不要瞎搞!!!! 做到以上三点能高35分qwq T1 江城唱晚 你看数据那么大,显然又是一道数学题. 这里有n个种海棠 ...
- MY TESTS
励志整理所有的n次考试的博客: [五一qbxt]test1 [五一qbxt]test2 [校内test]桶哥的问题 [6.10校内test] noip模拟 6.12校内test [6.12校内test ...
- Android Notification使用
一 Notification的类别 1.状态栏和抽屉式通知 //获取NotificationManager对象 val notificationManager = getSystemService(N ...
- 【贪心】【P5521】[yLOI2019] 梅深不见冬
B [yLOI2019] 梅深不见冬 Background 风,吹起梅岭的深冬:霜,如惊涛一样汹涌:雪,飘落后把所有烧成空, 像这场,捕捉不到的梦. 醒来时已是多年之久,宫门铜环才长了铁锈, 也开始生 ...
- 用FSM一键制作逐帧动画雪碧图 Vue2 + webpack
因为工作需要要将五六十张逐帧图拼成雪碧图,网上想找到一件制作工具半天没有找到,就自己用canvas写了一个. 写成之后就再没有什么机会使用了,因此希望有人使用的时候如果遇到bug了能及时反馈给我. 最 ...
随机推荐
- Java第十六天,list接口
List接口 1.三大特点: ① 有序.② 有索引. ③ 允许存在重复元素. 注意: ① 利用list接口的索引执行操作时,要防止索引越界引起的程序错误. 2.基本使用: 针对List接口有索引的特点 ...
- 【Mongodb】视图 && 索引
准备工作 准备2个集合的数据,后面视图和索引都会用到1个订单集合,一个收款信息集合 var orders = new Array(); var shipping = new Array(); var ...
- Git应用详解第五讲:远程仓库Github与Git图形化界面
前言 前情提要:Git应用详解第四讲:版本回退的三种方式与stash 这一节将会介绍本地仓库与远程仓库的一些简单互动以及几款常用的Git图形化界面,让你更加方便地使用git. 一.Git裸库 简单来说 ...
- tf.train.MomentumOptimizer 优化器
tf.train.MomentumOptimizer( learning_rate, momentum, use_locking=False, use_nesterov=False, name='Mo ...
- SQL数据类型:nchar,char,varchar,nvarchar 的区别和应用场景
概括: char:固定长度,存储ANSI字符,不足的补英文半角空格.CHAR存储定长数据很方便,CHAR字段上的索引效率级高,比如定义CHAR(10),那么不论你存储的数据是否达到了10个字节,都要占 ...
- Pytest系列(23)- allure打标记,@allure.feature()、@allure.story()、@allure.severity()的详细使用
如果你还想从头学起Pytest,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1690628.html 前言 前面几篇文章主要介绍了all ...
- Git敏捷开发--rebase命令
git rebase是git下比较常用的命令,以下记录自己遇到较多的使用场景. 合并分支 在多人协作的项目中,拉分支是很常见的事情,经常需要同步自己的分支与远端master分支一致,有两种方式: gi ...
- 菜鸡试飞----SRCの信息收集手册
whois信息 微步在线 https://x.threatbook.cn/ 站长之家 http://whois.chinaz.com/ dns信息-----检测是否存在dns域传送漏洞 子域名的收集 ...
- XSS语义分析的阶段性总结(一)
本文作者:Kale 前言 由于X3Scan的研发已经有些进展了,所以对这一阶段的工作做一下总结!对于X3Scan的定位,我更加倾向于主动+被动的结合.主动的方面主要体现在可以主动抓取页面链接并发起请求 ...
- JAVA快速排序代码实现
通过一趟排序将要排序的数据分割成独立的两部分:分割点左边都是比它小的数,右边都是比它大的数.然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 快速 ...