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

Balanced 01-String

Balanced 01-String

题目描述

小苯有一个长度为 $n$ 的字符串 $s$,只包含字符 $\texttt{'0'}$、$\texttt{'1'}$ 和 $\texttt{'?'}$。

他定义一个 $01$ 字符串是平衡的,当且仅当字符串中所有相邻两个字符相同的对数(即满足 $s_i = s_{i+1}$ 的 $i$ 的数量)是偶数。

(特别的,长度为 $1$ 的 $01$ 串必然是平衡的,因为此时相邻相同对数为 $0$,$0$ 也是偶数。)

小苯可以将每个 $\texttt{'?'}$ 替换为 $\texttt{'0'}$ 或 $\texttt{'1'}$。你的任务是求出,在所有可能的替换结果中,有多少个 $01$ 字符串是平衡的?(结果对 $998244353$ 取模。)

输入描述:

第一行一个整数 $T\ (1 \leqq T \leqq 10)$,表示测试数据组数。

接下来 $T$ 行,每行一个字符串 $s \ (1 \leqq |s| \leq 5 \times 10^5)$,只包含 $\texttt{'0'}$、$\texttt{'1'}$、$\texttt{'?'}$。

保证所有测试数据的字符串长度 $n$ 之和不超过 $5 \times 10^5$。

输出描述:

对于每组数据,输出一个整数表示满足条件的 $01$ 字符串数量对 $998244353$ 取模的结果。

示例1

输入

2
0?1
????

输出

0
8

说明

第一组数据:$s = \texttt{" 0?1"}$,两种替换:

$\texttt{"001"}$:相邻相同对数为 $1$($\texttt{"00"}$),奇数,不平衡。

$\texttt{"011"}$:相邻相同对数为 $1$($\texttt{"11"}$),奇数,不平衡。

输出 $0$。

 

解题思路

  先给出容易想到的一般做法,直接无脑考虑 dp 就行了。定义 $f(i,j,k)$ 表示前 $i$ 个字符中,第 $i$ 个字符为 $j \in \{0,1\}$ ,且相邻相同对数的奇偶性为 $k \in \{0,1\}$ 时的方案数。根据第 $i-1$ 个字符的类型进行状态转移,状态转移方程为 $$f(i,j,k) = \sum\limits_{j=0}^{1}{[s_i=j]\sum\limits_{k=0}^{1}{f(i-1,0,[j=0] \oplus k) + f(i-1,1,[j=1] \oplus k)}}$$

  需要注意的是,当 $s_i = \texttt{?}$ 时,$s_i$ 既可以取 $0$ 或 $1$。最后要求的答案就是 $f(n,0,0) + f(n,1,0)$。

  AC 代码如下,时间复杂度为 $O(n)$:

#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int N = 5e5 + 5, mod = 998244353;char s[N];
int f[N][2][2];void solve() {cin >> s;int n = strlen(s);memset(f[0], 0, sizeof(f[0]));if (s[0] == '0' || s[0] == '?') f[0][0][0] = 1;if (s[0] == '1' || s[0] == '?') f[0][1][0] = 1;for (int i = 1; i < n; i++) {memset(f[i], 0, sizeof(f[0]));for (int j = 0; j <= 1; j++) {if (s[i] != '?' && s[i] - '0' != j) continue;for (int k = 0; k <= 1; k++) {for (int u = 0; u <= 1; u++) {f[i][j][k] = (f[i][j][k] + f[i - 1][u][(j == u) ^ k]) % mod;}}}}cout << (f[n - 1][0][0] + f[n - 1][1][0]) % mod << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

  下面给出本题的一个很巧妙的做法。容易知道长度为 $n$ 的字符串有 $n-1$对相邻位置。假设其中相同对数的数量为 $a$,不同对数的数量为 $b$,那么有 $a+b=n-1$。由于要求 $a$ 为偶数,即 $n-1-b$ 为偶数,等价于 $b$ 与 $n-1$ 的奇偶性相同,即 $b \equiv n-1 \pmod{2}$。其中 $n-1$ 是定值,因此 $(n-1) \bmod 2$ 是确定的。

  而 $b \bmod 2 = \left( \sum\limits_{i=1}^{n-1}{[s_i \ne s_{i+1}]} \right) \bmod 2$。由于最终的 $s_i$ 只有 $0$ 和 $1$ 两种取值,因此 $[s_i \ne s_{i+1}] = s_i \oplus s_{i+1}$,所以 $\left( \sum\limits_{i=1}^{n-1}{[s_i \ne s_{i+1}]} \right) \bmod 2 = \left( \sum\limits_{i=1}^{n-1}{s_i \oplus s_{i+1}} \right) \bmod 2$。其中每一项成对出现并抵消,且在模 $2$ 加法下求和等价于逐项异或,因此最终有 $b \bmod 2 = s_1 \oplus s_n$。所以 $a$ 是偶数等价于 $s_1 \oplus s_n = (n-1) \bmod 2$。

  这也意味着该条件的满足只与 $s$ 首尾两个字符的取值有关,而与中间字符 $s_2, s_3, \dots, s_{n-1}$ 无关。只要首尾固定后,无论中间取什么值,$b$ 的奇偶性都是一样的。因此假设中间位置有 $c$ 个 $\texttt{?}$,那么就会贡献 $2^c$ 种方案。

  所以我们只需枚举首尾字符所有可能的取值(若为 $\texttt{?}$ 则可取 $0$ 和 $1$,否则只能取确定的值),对于每一种合法的首尾组合,若其异或值恰好等于 $(n-1) \bmod 2$,则将 $2^c$ 累加到答案。

  AC 代码如下,时间复杂度为 $O(n)$:

#include <bits/stdc++.h>
using namespace std;typedef long long LL;const int mod = 998244353;void solve() {string s;cin >> s;int p = 1;for (int i = count(s.begin() + 1, s.begin() + max<int>(1, s.size() - 1), '?'); i; i--) {p = 2 * p % mod;}int ret = 0;for (char i = '0'; i <= '1'; i++) {if (s[0] != '?' && s[0] != i) continue;for (char j = '0'; j <= '1'; j++) {if (s.back() != '?' && s.back() != j) continue;if (~(s.size() - 1 - (i ^ j)) & 1) ret = (ret + p) % mod;}}cout << ret << '\n';
}int main() {ios::sync_with_stdio(false);cin.tie(nullptr);int t;cin >> t;while (t--) {solve();}return 0;
}

 

参考资料

  牛客周赛127题目讲解:https://www.bilibili.com/video/BV1qoksBzEtg/

http://www.jsqmd.com/news/280609/

相关文章:

  • AI大模型学习全攻略:零基础入门、35岁转行可行性与就业前景
  • AI率过高别慌!这6个免费降AI工具亲测有效,学生党拯救论文指南
  • D6 707.设计链表
  • 基于SpringBoot+Vue一鹿租车公司车辆管理系统的设计与实现
  • 毕业党救星!5个降AI率工具大公开,亲测好用,能帮你把AI率降低80%以上
  • 实验室智能监控系统实战源码-基于YOLOv8的实时目标检测与PyQt5可视化界面
  • 如何在idea中创建mavenweb项目
  • AI率过高有救了!这5个工具实测能打,可将论文AIGC痕迹大幅降低80%
  • Java毕设项目推荐-基于springboot+vue的全国走失儿童认领与登记系统【附源码+文档,调试定制服务】
  • 开箱即用的番茄叶片病害识别平台|YOLOv8+PyQt5实战指南
  • 工控人注意了:Windows近期系统更新会导致你电脑的西门子软件TIA Portal 无法使用,你中招了吗?
  • 计算机Java毕设实战-基于springboot的走失儿童认领与登记系统基于springboot+vue的javaweb宝贝回家走失儿童报备【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • 学生党必看:3步轻松改写AI文献综述,教你如何用AI把AI率从80%降到5%!
  • 强烈安利MBA必备TOP8 AI论文软件
  • 基于SpringBoot+Vue医疗陪护服务平台的设计与实现
  • Java计算机毕设之基于springboot+vue的走失儿童认领与登记系统基于SpringBoot的宝贝回家走失儿童报备系统(完整前后端代码+说明文档+LW,调试定制等)
  • 【第1章>第17节】图像黒色顶帽理论分析与MATLAB仿真测试
  • AI与Python双驱动计量经济学多源数据处理、机器学习预测及复杂因果识别
  • Java网络编程:InetAddress 详解
  • 论文AI率过高被警告?学生党的急救方案:降AI工具一键改写,亲测有效!
  • Java毕设项目:基于springboot的走失儿童认领与登记系统(源码+文档,讲解、调试运行,定制等)
  • HEX文件合并全攻略:从原理到实战
  • Kubernetes Dashboard部署与可视化管理实战
  • 还在为AI率头疼?学生党福音:降AI工具免费降重攻略,轻松通过学校AI检测
  • LU,大小鼠脑损伤打击器 脑损伤打击器 自由落体打击器
  • 论文中的关键技术---机器学习与深度学习
  • 警告:论文的AI味太重了!不想延毕就看这篇:降AI工具辅助去AI化实战指南,从50%降到5%
  • 【毕业设计】基于springboot的走失儿童认领与登记系统(源码+文档+远程调试,全bao定制等)
  • 论文救星:6款免费降AI率工具深度体验,大幅降低论文AI痕迹,快速降重80%以上
  • AspNetCore开发笔记:WebApi项目集成企业微信和公众号