Solution -「AGC 058D」Yet Another ABC String
\newcommand{\chr}[1]{\underline{\texttt{#1}}}
\]
\(\mathscr{Description}\)
Link.
给定 \(a,b,c\) 求由 \(a\) 个 \(\chr A\), \(b\) 个 \(\chr B\), \(c\) 个 \(\chr C\) 组成的, 不存在子串 \(\chr{ABC},\chr{BCA},\chr{CAB}\) 的字符串数量. 答案模 \(998244353\).
\(a,b,c\le10^6\).
\(\mathscr{Solution}\)
不合法单元 \(\chr{ABC},\chr{BCA},\chr{CAB}\) 之间可能重叠, 所以我们难以使用平凡的容斥消除合法限制. 引入更广义的容斥? 考虑计算长度为 \(k\) 的一种不合法单元循环串 \(L_k=(\chr{ABC})^{+\infty}[:k]\) 的容斥系数 \(c_k\). 本质上, 这一字符串在容斥过程中由连续的钦定不合法单元拼接而成. 因此当 \(L_k\to L_{k+1}\) 时, 为了使 \(L_{k+1,k+1}\) 被钦定入 \(L_{k+1}\), 必须钦定 \(L_{k+1}[k-1:]\) 不合法. 也就是说, \(k-1\) 必然被钦定为非法单元左端点. 而再前面一个左端点就能取 \(k-2\) 或 \(k-3\), 对应 \(L_k\) 或 \(L_{k-1}\) 的情景. 因此有 \(c_{k+1}=-(c_k+c_{k-1})\), 边界为 \(c_1=1,c_2=0\). 当然, 这也就说明 \(c_k=[k\equiv1\pmod3]-[k\equiv0\pmod3]\).
接下来容斥 DP. 令 \(f(i,j)\) 表示完成了对 \([1,i]\) 的容斥, 有 \(j\) 个字符未被非法单元确定的方案数. 则
\]
注意两个带容斥系数项的处理. 非法单元循环实际上有 \((\chr{ABC})^{\infty},(\chr{BCA})^{+\infty},(\chr{CAB})^{+\infty}\), 当 \(k\bmod3=1\) 时, 需要确定第一个, 但 \(\chr A,\chr B,\chr C\) 的消耗量不一样, 所以需要计入 \(j\); 当 \(k\bmod3=0\) 时, 直接算上三种方案就行.
先来表示出答案,
\]
组合数统一确定了 \(f\) 中的未被确定字符. 可见, 我们需要求 \(f(n,\star)\).
需要优化, 不过后面的过程都很初等了. 引入 \(F(x,y)=\sum_{i,j}f(i,j)x^iy^j\), 那么
\]
令转移系数整体为 \(T(x,y)\), 化简得
\]
代回解得
\]
提取单项系数容易做到 \(\mathcal O(1)\). 那么本题就 \(\mathcal O(n)\) 完成了.
\(\mathscr{Code}\)
/*+Rainybunny+*/
#include <bits/stdc++.h>
#define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
#define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
const int MAXN = 3e6, MOD = 998244353;
int n, a, b, c, fac[MAXN + 5], ifac[MAXN + 5], pwr[MAXN + 5];
inline int mul(const int u, const int v) { return 1ll * u * v % MOD; }
inline void subeq(int& u, const int v) { (u -= v) < 0 && (u += MOD); }
inline int sub(int u, const int v) { return (u -= v) < 0 ? u + MOD : u; }
inline void addeq(int& u, const int v) { (u += v) >= MOD && (u -= MOD); }
inline int add(int u, const int v) { return (u += v) < MOD ? u : u - MOD; }
inline int mpow(int u, int v) {
int ret = 1;
for (; v; u = mul(u, u), v >>= 1) ret = mul(ret, v & 1 ? u : 1);
return ret;
}
inline void init() {
fac[0] = pwr[0] = 1;
rep (i, 1, n) fac[i] = mul(i, fac[i - 1]), pwr[i] = mul(2, pwr[i - 1]);
ifac[n] = mpow(fac[n], MOD - 2);
per (i, n - 1, 0) ifac[i] = mul(i + 1, ifac[i + 1]);
}
inline int bino(const int u, const int v) {
return u < v ? 0 : mul(fac[u], mul(ifac[v], ifac[u - v]));
}
/** Calculate [x^uy^v](1-xy+2x^3)^{-1}. */
inline int calc(const int u, const int v) {
if ((u + 2 * v) % 3) return 0;
int k = (u + 2 * v) / 3;
if (k < v) return 0;
return mul(bino(k, v), (k - v & 1 ? sub : add)(0, pwr[k - v]));
}
int main() {
scanf("%d %d %d", &a, &b, &c);
n = a + b + c, init();
int ans = 0;
rep (i, 0, std::min({ a, b, c })) {
addeq(ans, mul(mul(fac[n - 3 * i], mul(ifac[a - i],
mul(ifac[b - i], ifac[c - i]))),
sub(calc(n, n - 3 * i), calc(n - 3, n - 3 * i))));
}
printf("%d\n", ans);
return 0;
}
Solution -「AGC 058D」Yet Another ABC String的更多相关文章
- Solution -「AGC 036D」「AT 5147」Negative Cycle
\(\mathcal{Descriprtion}\) Link. 在一个含 \(n\) 个结点的有向图中,存在边 \(\lang i,i+1,0\rang\),它们不能被删除:还有边 \(\l ...
- Solution -「AGC 016F」Games on DAG
\(\mathcal{Description}\) Link. 给定一个含 \(n\) 个点 \(m\) 条边的 DAG,有两枚初始在 1 号点和 2 号点的棋子.两人博弈,轮流移动其中一枚棋 ...
- Solution -「AGC 026D」Histogram Coloring
\(\mathcal{Description}\) Link. 有 \(n\) 列下底对齐的方格纸排成一行,第 \(i\) 列有 \(h_i\) 个方格.将每个方格染成黑色或白色,求使得任意完 ...
- Solution -「AGC 004E」「AT 2045」Salvage Robots
\(\mathcal{Description}\) Link. 有一个 \(n\times m\) 的网格.每个格子要么是空的,要么有一个机器人,要么是一个出口(仅有一个).每次可以命令所有机 ...
- Solution -「AGC 012F」「AT 2366」Prefix Median
\(\mathcal{Description}\) Link. 给定序列 \(\{a_{2n-1}\}\),将 \(\{a_{2n-1}\}\) 按任意顺序排列后,令序列 \(b_i\) 为前 ...
- Solution -「AGC 010C」「AT 2304」Cleaning
\(\mathcal{Description}\) Link. 给定一棵 \(n\) 个点的无根树,点有点权,每次选择两个不同的叶子,使它们间的简单路径的所有点权 \(-1\),问能否将所有点 ...
- Solution -「AGC 019E」「AT 2704」Shuffle and Swap
\(\mathcal{Description}\) Link. 给定 \(01\) 序列 \(\{A_n\}\) 和 \(\{B_n\}\),其中 \(1\) 的个数均为 \(k\).记 \( ...
- Solution -「AGC 019F」「AT 2705」Yes or No
\(\mathcal{Description}\) Link. 有 \(n+m\) 个问题,其中 \(n\) 个答案为 yes,\(m\) 个答案为 no.每次你需要回答一个问题,然后得知这个 ...
- Solution -「AGC 013E」「AT 2371」Placing Squares
\(\mathcal{Description}\) Link. 给定一个长度为 \(n\) 的木板,木板上有 \(m\) 个标记点,第 \(i\) 个标记点距离木板左端点的距离为 \(x_i\ ...
- Solution -「AGC 003D」「AT 2004」Anticube
\(\mathcal{Description}\) Link. 给定 \(n\) 个数 \(a_i\),要求从中选出最多的数,满足任意两个数之积都不是完全立方数. \(n\le10^5\) ...
随机推荐
- 枚举(C语言)
1.枚举定义 枚举是 C 语言中的一种基本数据类型,用于定义一组具有离散值的常量,它可以让数据更简洁,更易读. 枚举类型通常用于为程序中的一组相关的常量取名字,以便于程序的可读性和维护性. 定义一个枚 ...
- 远程连接服务器时出现“这可能是由于CredSSP加密数据库修正”的错误提示的解决办法
当我们远程连接服务器时,有时候会出现以下提示,从而导致我们无法成功连接服务器,如下所述: 原因: 远程桌面使用的是"凭据安全支持提供程序协议 (CredSSP) ",这个协议在未修 ...
- 6 年 30k star,这个明星项目停止更新!
大家好,我是程序员鱼皮.就在昨天,GitHub 上一个知名的开源项目 Easy Excel 官宣停止更新,下面是官方原文: 公告中表示,Easy Excel 将进入维护模式,会进行 Bug 修复,但不 ...
- 现代IT基础设施管理(1):Terraform初识和小试牛刀
基础设施包括各种云,像国内的阿里云.腾讯云和华为云,国外的AWS.微软Azure云和谷歌云,还有Kubernetes和OpenStack,都可以用Terraform进行资源管理.使用基础设施即代码(I ...
- 22.使用Rancher2.0搭建Kubernetes集群
使用Rancher2.0搭建Kubernetes集群 中文文档:https://docs.rancher.cn/docs/rancher2 安装Rancher2.0 使用下面命令,我们快速的安装 # ...
- 13.Kubernetes核心技术Ingress
Kubernetes核心技术Ingress 前言 原来我们需要将端口号对外暴露,通过 ip + 端口号就可以进行访问 原来是使用Service中的NodePort来实现 在每个节点上都会启动端口 在访 ...
- end.jenkins的备份和迁移
数据备份: 进入安装目录 cd /var/lib/jenkins 进入到主目录下,可以看到很多文件,是否需要全部打包呢?其实我们只需要打包4个文件就可以了. 如上图所示分别是 config.xml ...
- .NET Core 线程(Thread)底层原理浅谈
简介 线程,进程,协程基本概念不再赘述. 原生线程和用户线程 原生线程 在内核态中创建的线程,只服务于内核态 用户线程 由User Application创建的线程,该线程会在内核态与用户态中间来回穿 ...
- node-npm发布包-package.json中bin的用法
前言 用过angular-cli,create-react-app这些脚手架的朋友们,不知道你们有没有好奇过,为什么安装这些脚手架后,可以使用类似ng generate之类的命令.小弟研究了以下,原来 ...
- 使用tensorboard可视化模型
Tensorboard是TF自带的可视化工具.它可以让我们从各个角度观察与修改模型,比如观察模型在训练时的loss动态变化曲线而无需在迭代完毕后再画图.绘制神经网络的结构图.调节超参数等.下面以最简单 ...