【题目背景】

岁岁花藻檐下共将棠梨煎雪。

自总角至你我某日辗转天边。

天淡天青,宿雨沾襟。

一年一会信笺却只见寥寥数言。

——银临《棠梨煎雪》

【问题描述】

扶苏正在听《棠梨煎雪》的时候,山东省实验中学的 zzh 发来一道IOI2018集训队 互测题:我切了这集训队题,辣鸡扶苏快过来做题。扶苏定睛一看,这不 s* 题嘛,写 了一发交上去才发现自己看错题目了。但是写完的代码不能浪费,于是就有了这道题。

歌词中的主人公与她的朋友一年会有一次互相写信给对方,一共通信了 m 年。为了 简化问题,我们认为他们每封信的内容都是一条二进制码,并且所有二进制码的长度都 是 n。即每封信的内容都是一个长度为 n 的字符串,这个字符串只含字符 0 或 1。

这天她拿出了朋友写给她的所有信件,其中第 i 年的写的信件编号为 i。由于信件 保存时间过久,上面有一些字符已经模糊不清,我们将这样的位置记为 ?,? 字符可以 被解释为 0 或 1。由于她的朋友也是人,符合人类的本质,所以朋友在一段连续的时间 中书写的内容可能是相同的。现在她想问问你,对于一段连续的年份区间 [l,r] 中的所 有信件,假如朋友在这段时间展示了人类的本质,所写的是同一句话,那么这一句话一 共有多少种可能的组成。也即一共有多少字符串 S,满足在这个区间内的所有信件的内 容都可能是 S。

一个长度为 n 的只含 0,1,? 的字符串 A 可能是一个字符串 B 当且仅当 B 满足如 下条件:

  1. B 的长度也是 n
  2. B 中只含字符 0,1
  3. A 中所有为 0 的位置在 B 中也是 0
  4. A 中所有为 1 的位置在 B 中也是 1
  5. A 中为 ? 的位置在 B 中可以为 0 也可以是 1

同时她可能会突然发现看错了某年的信的内容,于是他可能会把某一年的信的内容 修改为一个别的只含 0,1,? 的长度为 n 的字符串。

【输入格式】

输入文件名为 lin.in。

输入文件中有且仅有一组数据,第一行为三个正整数 n,m,q,代表字符串长度,字 符串个数和操作次数。

下面 m 行,每行是一个长度为 n 的字符串,第 i 个字符串代表第 i 年信的内 容。

下面 q 行,每行的第一个数字是操作编号 opt。

如果 opt=0,那么后面接两个整数 [l,r],代表一次查询操作

如果 opt=1,那么后面接一个整数 pos,在一个空格后会有一个长度为 n 的字符 串,代表将第 pos 个字符串修改为新的字符串。

【输出格式】

输出文件名为 lin.out。

对于每个查询操作,输出一行一个整数代表答案。


SOLUTION:

子任务 1: 0 次询问,直接 freopen 即可得分,期望得分 5 分。

子任务 2: 考虑在询问的时候枚举所有可能出现的串,然后遍历区间所有的字符串看看是否 合法。由于字符串长度为 n,且每个位置只可能是 0/1,所以一共有 2 n 中情况。时间 复杂度 O(2 nmq),期望得分 10 分。

子任务 3: 考虑对于一段区间的所有字符串的第 x 个字符,一共有四种可能,确定为 0,确 定为 1,都可以,都不可以。如果都不可以则输出0,如果确定为 0 或 1,则这一位 只有一种可能,否则有两种可能,根据乘法原理,如果有 a 个位置都可以,则会有 2 a 种可能。输出答案即可。时间复杂地 O(nmq),期望得分 15 分。

(感觉我的代码就是介个思路呀,但是我肿么没有分呢??又玄学啦(改了几行吧,就对了可海星))

(啊经过一晚上不懈努力,我终于知道我错哪了:1.cnt1没有memset,然后l==r的特判也不到家(所以emm对自己无语惹))

45pts(数据水的说qwq)

#include<bits/stdc++.h>using namespace std;inline int read(){int ans=0;char last=' ',ch=getchar();while(ch<'0'||ch>'9') last=ch,ch=getchar();while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();if(last=='-') ans=-ans;return ans;
}int n,m,q,opt,l,r;
char s[100008][31];int cx(int l,int r){long long cnt1;int ans=1;int qj=r-l+1;for(int i=1;i<=n;i++){char d=' ';cnt1=0;for(int j=l;j<=r;j++){if(s[j][i]=='?'){cnt1++;continue;}if(d==' ') d=s[j][i];if(d==s[j][i]) continue;else return 0;}if(cnt1==qj) ans*=2;}return ans;
}int main(){n=read();m=read();q=read();if(m==1)return 0;for(int i=1;i<=m;i++)scanf("%s",s[i]+1);for(int i=1;i<=q;i++){opt=read();if(opt==0){l=read();r=read();cout<<cx(l,r)<<"\n";}else {char ss[31];int f=read();scanf("%s",ss+1);for(int i=1;i<=n;i++){s[f][i]=ss[i];}}}return 0;
} 

45pts Code

#include<bits/stdc++.h>using namespace std;inline int read(){int ans=0;char last=' ',ch=getchar();while(ch<'0'||ch>'9') last=ch,ch=getchar();while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();if(last=='-') ans=-ans;return ans;
}int n,m,q,opt,l,r;
char s[100008][31];int cx(int l,int r){int cnt1[31];memset(cnt1,0,sizeof(cnt1));if(l==r) {int cnt=1;for(int i=1;i<=n;i++)if(s[l][i]=='?') cnt*=2;return cnt;}int k=l;for(int i=1;i<=n;i++){char d='x';for(int j=l;j<=r;j++){if(s[j][i]=='?'){cnt1[i]++;continue;}if(d=='x') d=s[j][i];if(d==s[j][i]) continue;else return 0;}}int ans=1;int qj=r-l+1;for(int i=1;i<=n;i++){if(cnt1[i]==qj) ans*=2;else ans*=1;}return ans;
}int main(){freopen("lin.in","r",stdin);freopen("lin.out","w",stdout);n=read();m=read();q=read();if(m==1)return 0;for(int i=1;i<=m;i++)scanf("%s",s[i]+1);for(int i=1;i<=q;i++){opt=read();if(opt==0){l=read();r=read();cout<<cx(l,r)<<"\n";}else {char ss[31];int f=read();scanf("%s",ss+1);for(int i=1;i<=n;i++){s[f][i]=ss[i];}}}return 0;
} 

最少改动的45pts Code

好了接下来是正解做法了(我不保证我能看懂因为zay太爱用指针啦)

的一部分(突然发现还有好多子任务的说)

子任务 4:

考虑 n 只有 30,可以状压到 int 中,具体的,维护两个 int,第一个 int 维 护对应位是否确定为 0 或 1,第二个 int 维护如果确定为 0 或 1 了则具体是 0 还 是 1。通过位运算操作一下可以快速的该区间内的信息。

具体的,考虑 a1,a2 是从 L 到某个位置左侧的区间信息,b1,b2 是该位置的区 间信息,如果该询问没有能匹配的字符串,则 (a1|b1)&(a2^b2) 应该不为 0,输出 0 即可。否则 a1=a1|b1;a2=(a1|b1)&(a2&b2)。

验题人的神仙做法是维护一个 longlong,两个二进制位一组,01 代表确定为 0,10代表确定为 1,11 代表都可以,00 代表不合法,维护的时候直接按位与即可。 时间复杂度 O(mq),期望得分 15 分。

子任务 5:

考虑 n 只有 1,可以开一个线段树维护每个位置的字符是什么,pushup的时候操 作一下即可。时间复杂度 O(q logm),期望得分 15 分。

子任务 6:

世界上没有什么事情是开一棵线段树不能解决的。如果有,那就开 30 棵。时间 复杂度 O(nq logm),期望得分 10 分。

子任务 7:

考虑用一棵线段树维护子任务 4 中的状压信息,通过位运算可以把 n 省掉,于 是总复杂度 O(nq + qlogm),期望得分 30 分。

#include <cstdio>template <typename T>
inline void qr(T &x) {char ch = getchar(), lst = ' ';while ((ch > '9') || (ch < '0')) lst = ch, ch=getchar();while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = getchar();if (lst == '-') x = -x;
}const int maxn = 100010;int n, m, q;
char s[maxn][35];#ifdef ONLINE_JUDGE
int Ans;
#endifstruct Tree {Tree *ls, *rs;int l, r, x/*int1*/, y/*int2*/;bool leg;//判断
Tree() {ls = rs = NULL;l = r = x = y = 0;leg = true;}void pushup() {if (!(this->ls->leg && this->rs->leg)) {//左右子树都不合法 this->leg = false;} else {if ((this->ls->x & this->rs->x) & (this->ls->y ^ this->rs->y)) {//只有当左右儿子对应位置是否全为1或0都相同并且左右儿子对应的y不相同时,显然不合法 this->leg = false;} else {this->leg = true;this->x = this->ls->x | this->rs->x;this->y = this->ls->y | this->rs->y;}}}
};
Tree *rot;void ReadStr(char *p);
void Update(const int x);
void Query(const int l, const int r);
void update(Tree *const u, const int p);
Tree query(Tree *u, const int l, const int r);
void build(Tree *const u, const int l, const int r);int main() {freopen("lin.in", "r", stdin);freopen("lin.out", "w", stdout);qr(n); qr(m); qr(q);for (int i = 1; i <= m; ++i) {ReadStr(s[i] + 1);//读入一串字符串的神仙操作
  }build(rot = new Tree, 1, m);int opt, l, r;while (q--) {opt = 0; qr(opt);if (opt == 0) {l = r = 0; qr(l); qr(r);Query(l, r);} else {l = 0; qr(l);ReadStr(s[0] + 1);Update(l);}}
#ifdef ONLINE_JUDGEprintf("%d\n", Ans);
#endifreturn 0;
}void ReadStr(char *p) {do *p = getchar(); while ((*p != '0') && (*p != '1') && (*p != '?'));do *(++p) = getchar(); while ((*p == '0') || (*p == '1') || (*p == '?'));*p = 0;
}void build(Tree *const u, const int l, const int r) {if ((u->l = l) == (u->r = r)) {//叶节点 for (int i = 1; i <= n; ++i) {//直接扫描记录即可 if (s[l][i] != '?') {u->x |= 1 << i;if (s[l][i] == '1') {u->y |= 1 << i;}}}} else {//不是叶节点,递归建树; int mid = (l + r) >> 1;build(u->ls = new Tree, l, mid);build(u->rs = new Tree, mid + 1, r);u->pushup();}
}Tree query(Tree *u, const int l, const int r) {if ((u->l > r) || (u->r < l)) return Tree();if ((u->l >= l) && (u->r <= r)) return *u;Tree _ret;auto ll = query(u->ls, l, r), rr = query(u->rs, l, r);_ret.ls = &ll; _ret.rs = &rr;_ret.pushup();return _ret;
}void Query(const int l, const int r) {auto _ret = query(rot, l, r);if (!_ret.leg) {
#ifndef ONLINE_JUDGEputs("0");
#endif} else {int ans = 1;for (int i = 1; i <= n; ++i) if (!(_ret.x & (1 << i))) {ans <<= 1;}
#ifdef ONLINE_JUDGEAns ^= ans;
#elseprintf("%d\n", ans);
#endif}
}void update(Tree *u, const int p) {if (u->ls) {if (u->ls->r >= p) {update(u->ls, p);} else {update(u->rs, p);}u->pushup();} else {*u = Tree();u->l = u->r = p;for (int i = 1; i <= n; ++i) {if (s[0][i] != '?') {u->x |= 1 << i;if (s[0][i] == '1') {u->y |= 1 << i;}}}}
}void Update(const int x) {update(rot, x);
}

我尽力了,但我真的没有全看懂

end-

转载于:https://www.cnblogs.com/zhuier-xquan/p/11093693.html

【6.24校内test】T3 棠梨煎雪相关推荐

  1. 计算机音乐谱棠梨煎雪,天谕手游棠梨煎雪乐谱_棠梨煎雪乐谱代码分享_3DM手游...

    在天谕手游中玩家可以把自己喜欢的歌写进乐谱,在这里小编给大家分享一下棠梨煎雪这首歌的乐谱代码,喜欢的小伙伴不要错过哦,下面小编给大家带来<天谕手游>棠梨煎雪乐谱代码分享,不清楚代码的小伙伴 ...

  2. 计算机音乐谱棠梨煎雪,天谕手游棠梨煎雪乐谱代码分享

    天谕手游棠梨煎雪乐谱代码是什么?<棠梨煎雪>是一首由银临演唱的原创古风歌曲,收录于专辑<腐草为萤>中.接下来小编为大家带来了天谕手游棠梨煎雪乐谱代码分享,希望可以帮助到大家. ...

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

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

  4. 计算机音乐谱棠梨煎雪,棠梨煎雪钢琴谱-银临-冬寒思雪又一年

    棠梨煎雪钢琴谱-银临-冬寒思雪又一年 棠梨煎雪-银临 词:商连 曲:灰原穷 编曲:灰原穷 青鲤来时遥闻春溪声声碎 嗅得手植棠梨初发轻黄蕊 待小暑悄过新梨渐垂 来邀东邻女伴撷果缓缓归 旧岁采得枝头细雪 ...

  5. 7.24 校内模拟赛

    题目链接:[已去世] T1 送你一个DAG 题目描述:给定一个DAG,求所有$1$到$i$的路径的长度的$k$次方之和$\mathrm{mod} \ 998244353$. 数据范围:$n\leq 1 ...

  6. 交友软件上的两种网友类型......

    1 轻轻松松月入五千的方法 (素材来源网络,侵删) ▼ 2 像极了期末复习的你 (via.段子楼,侵删) ▼ 3 听说你想要中国的熊猫 ▼ 4 听说学校附近有野人出没 (素材来源网络,侵删) ▼ 5 ...

  7. 表白套路计算机公式,数学情话大全浪漫情话套路句子 数学情话表白公式短句说说合集...

    都说理科生很古板,学理科的也一般都是直男直女,特别是学数学的,除了公式之外还是公式,但是就是这样枯燥古板的数学,却也有着很多人不懂的情话表白句子哦.下面带来:数学情话大全浪漫情话套路句子 数学情话表白 ...

  8. 想让你看的评论:我还是很喜欢你

    我还是很喜欢你,像风走了八千里,不问归期. 一标准文艺风: 我还是很喜欢你,像夜空中星辰闪烁,霓虹迷离. 我还是很喜欢你,像云填满整片蓝天,一眼万年. 我还是很喜欢你,像日落前洒下的余晖,不忍离去. ...

  9. 计算机专业群名有内涵,微信群起名高端有内涵

    其实起的微信群名字,大家都会理解到哪些才是最好听的呢?其实都会觉得有些人的起的名字大家都会人呢我大哦都会比较好听的一切,都会是如何起的呢,微信群起名高端有内涵到底这样起才是最好听的呢,一起来看看微信群 ...

最新文章

  1. 创 keras_contrib 安装
  2. 开源工具之valgrind
  3. 如何吸收分数c语言,用C语言编程平均分数
  4. Ubuntu安装Nginx+PHP+Memcache+Mysql指导手册
  5. 谈谈产品开发团队的配置管理规则
  6. 审计日志删除 oracle,oracle audit,怎么审计ORACLE日志
  7. 黑客大佬:我是如何让50个文件一起骗过AI安防系统的?
  8. Python学习16 正则表达式2 re模块
  9. 基于IP的H.264关键技术
  10. 国庆活动延长三天!快来领取你的数据技术嘉年华门票!
  11. Salesforce 为什么要收购 Slack?
  12. java什么会引用传递_在java中为什么很多人说有值传递和引用传递?引用传递的本质...
  13. 重构手法之重新组织数据【1】
  14. vbs 窗体文字获取文档_MDI类型窗体设置背景图片
  15. Could not load NIB in bundle: 'NSBundle /Users/wyd/Library/Application Support/iPhone Simulator/5.0
  16. DSP 程序远程升级 / Bootloader设计指南(四)——Bootloader数据流
  17. java traingdx函数实现_提取伪彩色图像的信息
  18. 性能、应用、安装,选择LoRaWAN温湿度传感器的关键
  19. ORACLE LPAD()函数
  20. Python编程:使用os.urandom生成Flask的秘钥SECRET_KEY

热门文章

  1. 正版中国,一个不错的网站!
  2. 圣杯布局双飞翼布局认识
  3. Java入门 Day004 补充(switch语句 for循环)
  4. 伍迷创意随想集 之 电子菜谱系统
  5. 2021年11月中国乘用车品牌出口量排行榜:MGZS出口量突破2万辆,Top前五中有3个品牌归属上海股份(附月榜TOP150详单)
  6. 数据结构与算法-《开篇》
  7. 知乎高赞:为什么别选计算机专业?(看完我沉默了,为了财富自由还得学计算机专业)...
  8. Java快速开发平台,JEECG 3.7.5 Vue SPA单页面应用版本发布
  9. 搭建Spark Standalone集群
  10. 荃湾体育节是游客最喜欢的香港旅游项目