当前位置: 首页 > news >正文

《P5522 [yLOI2019] 棠梨煎雪》

题目背景

岁岁花藻檐下共将棠梨煎雪,
自总角至你我某日辗转天边。
天淡天青,宿雨沾襟,
一年一会信笺却只见寥寥数言。

——银临《棠梨煎雪》

题目描述

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

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

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

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

  • B 的长度也是 n 。
  • B 中只含字符 0,1
  • A 中所有为 0 的位置在 B 中也是 0
  • A 中所有为 1 的位置在 B 中也是 1
  • A 中为 ? 的位置在 B 中可以为 0 也可以是 1

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

输入格式

每个输入文件中都有且仅有一组测试数据。

输入数据第一行为三个用空格隔开的整数,分别代表代表字符串长度 n,字符串个数 m 和操作次数 q。

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

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

  • 如果 opt=0,那么后面接两个整数 [l, r],代表一次查询操作。
  • 如果 opt=1,那么后面接一个整数 pos,在一个空格后会有一个长度为 n 的字符串 t,代表将第 pos 个字符串修改为新的字符串 t。

输出格式

为了避免输出过大,请你输出一行一个数代表所有查询的答案异或和对 0 取异或的结果。

输入输出样例

输入 #1复制

3 3 5
010
0?0
1?0
0 1 2
0 2 3
1 3 0??
0 2 3
0 1 3

输出 #1复制

2

说明/提示

样例 1 解释

  • 对于第一次询问,只有串 010 符合要求。
  • 对于第二次询问,由于第二个串的第一位为 0,第三个串的第一位为 1,故没有串符合要求。
  • 修改后将第三个串修改为 0??
  • 对于第四次询问,有两个串符合要求,分别为 000 和 010
  • 对于第五次询问,只有 010 符合要求。

故答案为 1,0,2,1,他们的异或和再异或 0 的值为 2。


数据规模与约定

本题采用多测试点捆绑测试,共有 7 个子任务

子任务编号m=q=n=子任务分数
11015
21021021010
3100310031015
41004100043015
5100005500005115
6100006500063010
710000710000073030

对于全部的测试点,保证:

  • 1≤m≤105+7,0≤q≤106+7,1≤n≤30。
  • 0≤opt≤1,1≤pos≤m,1≤l≤r≤m。
  • si​,t 的长度均为 n 且只含有字符 0,1,?
  • 输入字符串的总长度不超过 5×106。数据在 Linux 下生成,即换行符不含 \r

提示
  • 请注意常数因子对程序效率造成的影响。
  • 请注意数据读入对程序效率造成的影响。
  • 请注意输入的问号为嘤文问号,即其 ASCII 值为 63

注: 为减少错误做法的通过率,时限于 2020 年 7 月由 2000ms 改为 1500ms

代码实现;

#include <ctime>
#include <cstdio>

namespace IPT {
    const int L = 1000000;
    char buf[L], *front=buf, *end=buf;
    char GetChar() {
        if (front == end) {
            end = buf + fread(front = buf, 1, L, stdin);
            if (front == end) return -1;
        }
        return *(front++);
    }
}

template <typename T>
inline void qread(T &x) {
    char ch = IPT::GetChar(), lst = ' ';
    while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
    while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
    if (lst == '-') x = -x;
}

namespace OPT {
    char buf[120];
}

template <typename T>
inline void qwrite(T x, const char aft, const bool pt) {
    if (x < 0) {
        x = -x, putchar('-');
    }
    int top=0;
    do {
        OPT::buf[++top] = static_cast<char>(x % 10 + '0');
    } while (x /= 10);
    while (top) putchar(OPT::buf[top--]);
    if (pt) putchar(aft);
}

template <typename T>
inline void qr(T &x) {
  char ch = IPT::GetChar(), lst = ' ';
  while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
  while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
  if (lst == '-') x = -x;
}

const int maxn = 100010;

int n, m, q;
char s[maxn][35];

#ifdef ONLINE_JUDGE
int Ans;
#endif

struct Tree {
  Tree *ls, *rs;
  int l, r, x, y;
  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)) {
        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() {
  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_JUDGE
  printf("%d\n", Ans);
#endif
  return 0;
}

void ReadStr(char *p) {
  do *p = IPT::GetChar(); while ((*p != '0') && (*p != '1') && (*p != '?'));
  do *(++p) = IPT::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_JUDGE
    puts("0");
#endif
  } else {
    int ans = 1;
    for (int i = 1; i <= n; ++i) if (!(_ret.x & (1 << i))) {
      ans <<= 1;
    }
#ifdef ONLINE_JUDGE
    Ans ^= ans;
#else
    printf("%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);
}

http://www.lryc.cn/news/578615.html

相关文章:

  • 如何分析大语言模型(LLM)的内部表征来评估文本的“诚实性”
  • 在 Docker 容器中使用内网穿透
  • 大语言模型推理系统综述
  • NLP——RNN变体LSTM和GRU
  • 关于vue2使用elform的rules校验
  • 深度学习进阶:自然语言处理的推荐点评
  • (LeetCode 面试经典 150 题) 42. 接雨水 (单调栈)
  • Gartner《Choosing Event Brokers to Support Event-DrivenArchitecture》心得
  • 振荡电路Multisim电路仿真实验汇总——硬件工程师笔记
  • .NET跨平台开发工具Rider v2025.1——支持.NET 10、C# 14
  • K8s Pod调度基础——2
  • Langgraph 学习教程
  • 位运算经典题解
  • python+uniapp基于微信小程序的流浪动物救助领养系统nodejs+java
  • 用 YOLOv8 + DeepSORT 实现目标检测、追踪与速度估算
  • SeaTunnel 社区 2 项目中选“开源之夏 2025”,探索高阶数据集成能力!
  • 华为设备 QoS 流分类与流标记深度解析及实验脚本
  • flv.js视频/直播流测试demo
  • 欢乐熊大话蓝牙知识24:LE Secure Connections 是 BLE 的安全升级术
  • 视频内存太大怎么压缩变小一点?视频压缩的常用方法
  • Nginx重定向协议冲突解决方案:The plain HTTP request was sent to HTTPS port
  • Apache HTTP Server部署全攻略
  • 第八十六篇 大数据排序算法:从厨房整理到分布式排序的智慧
  • DBA 命令全面指南:核心操作、语法与最佳实践
  • 爱回收平台接口开发指南
  • 变幻莫测:CoreData 中 Transformable 类型面面俱到(七)
  • 打造 AI 产品的前端架构:响应式、流式、智能交互三合一
  • 基于SSM万华城市货运服务系统的设计与实现
  • OpenCV CUDA模块设备层-----反向二值化阈值处理函数thresh_binary_inv_func()
  • Python学习Day48