[AGC040C] Neither AB nor BA
Description
一个长度为 n 的字符串是好的当且仅当它由 'A', 'B', 'C' 组成,且可以通过若干次删除除了"AB"和"BA"的连续子串变为空串。
问有多少个长度为 n 的好串,对 998244353 取模。
\(n\le 10 ^ 7\) , 保证 n 为偶数。
Solution
本题的关键在于转化题意,即找到一个更加简洁抽象的等价条件方便计数。
连续删除两个字符后发现每一个 A 和 B 的奇偶性没有改变。
这说明了奇数位置的 A 一定不能和偶数位置的 B 消除,偶数位置的 A 不能和奇数位置的B消除。
设奇数位置的 A 有 x 个,偶数位置的 B 有 y 个,偶数位置的非 B 字符有 n - y 个, 那么必须满足(即必要性):
x + y \le \frac n2
\]
所以有:
奇数位置上A的数量 + 偶数位置上B的数量\(\le \frac n 2\)
奇数位置上B的数量 + 偶数位置上A的数量\(\le \frac n 2\)
必要性显然。
仿照上式子记为:
a + b \le \frac n 2
\]
充分性可以考虑先吧序列的 C 都消掉,剩只需考虑 A 和 B 。
由于
\(a + c = b + d = \frac n 2\)
所以
\(a + d = b + c = \frac n 2\)
这样就必然可以找到一对 AA 或 BB 消去。
Thus,\(Ans = 3 ^ n - count(a + b > \frac n 2) - count(c + d > \frac n 2)\) 。
枚举有多少个 a + b (c + d) ,其余的位置就只有两种方案,用组合数算一下即可.
code
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
#define End exit(0)
#define LL long long
#define mp make_pair
#define SZ(x) ((int) x.size())
#define GO cerr << "GO" << endl
#define DE(x) cout << #x << " = " << x << endl
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
void proc_status()
{
freopen("/proc/self/status","r",stdin);
string s; while(getline(cin, s)) if (s[2] == 'P') { cerr << s << endl; return; }
}
template<typename T> inline T read()
{
register T x = 0;
register char c; register int f(1);
while (!isdigit(c = getchar())) if (c == '-') f = -1;
while (x = (x << 1) + (x << 3) + (c ^ 48), isdigit(c = getchar()));
return x * f;
}
template<typename T> inline bool chkmin(T &a,T b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a,T b) { return a < b ? a = b, 1 : 0; }
const int maxN = 1e7 + 2;
const int mod = 998244353;
int qpow(int a, int b)
{
int ans = 1;
for (; b; b >>= 1, a = 1ll * a * a % mod)
if (b & 1) ans = 1ll * ans * a % mod;
return ans;
}
inline void Inc(int &x) { x < 0 ? x += mod : 0; }
int fac[maxN + 2], ifac[maxN + 2], pw2[maxN + 2];
void init(int N = 1e7)
{
fac[0] = 1;
for (int i = 1; i <= N; ++i) fac[i] = (LL) fac[i - 1] * i % mod;
ifac[N] = qpow(fac[N], mod - 2);
for (int i = N - 1; i >= 0; --i) ifac[i] = (LL) ifac[i + 1] * (i + 1) % mod;
pw2[0] = 1;
for (int i = 1; i <= N; ++i) pw2[i] = pw2[i - 1] * 2ll % mod;
}
int C(int n, int m)
{
if (n < m) return 0;
return (LL) fac[n] * ifac[m] % mod * ifac[n - m] % mod;
}
int n;
void input() { n = read<int>(); }
void solve()
{
int ans = qpow(3, n);
for (int i = n / 2 + 1; i <= n; ++i)
Inc(ans -= 2ll * C(n, i) * pw2[n - i] % mod);
printf("%d\n", ans);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("xhc.in", "r", stdin);
freopen("xhc.out", "w", stdout);
#endif
input(), init(), solve();
return 0;
}
[AGC040C] Neither AB nor BA的更多相关文章
- @atcoder - AGC040C@ Neither AB nor BA
目录 @description@ @solution@ @accepted code@ @detail@ @description@ 给定偶数 N,求由 'A', 'B', 'C' 三种字符组成的字符 ...
- 静态链表实现 (A-B)U(B-A)
图中黄色部分为(A-B)U(B-A)的实际意义,用结构数组做静态链表来实现该表达式 大致流程是先建立A链表,接着将挨个输入的B中元素在A链表中遍历.如果没找到,就加到A链表结尾下标为endpointe ...
- 已知 $AB$, 求 $BA$
设 $A,B$ 分别是 $3\times 2$ 和 $2\times 3$ 实矩阵. 若 $\dps{AB=\sex{\ba{ccc} 8&0&-4\\ -\frac{3}{2}& ...
- 矩阵迹 tr(AB)=tr(BA)的证明
其实更为直观的理解是:AB与BA具有相同的对角线元素,因此tr(AB)=tr(BA)必然成立 ref:https://blog.csdn.net/silence1214/article/details ...
- AT5661-[AGC040C]Neither AB nor BA【模型转换】
正题 题目链接:https://www.luogu.com.cn/problem/AT5661 题目大意 一个包含\(A,B,C\)的序列,每次可以选择相邻的两个除了\(AB\)和\(BA\)的删去. ...
- AtCoder Grand Contest 040 C - Neither AB nor BA
传送门 好妙的题啊 首先容易想到简单容斥,统计合法方案数可以考虑总方案数减去不合法方案数 那么先考虑如何判断一个串是否合法,但是直接判断好像很不好搞 这时候就需要一些 $magic$ 了,把所有位置下 ...
- AGC040 Task C. Neither AB Nor BA
Observations 对一个长为 $2N$ 的序列重复下述操作:取走两个相邻且不同的元素.最后能把序列取空的充要条件是序列中不存在出现超过 $N$ 次的元素. 证明:必要性,取 $N$ 次最多能取 ...
- [ACM_图论] ZOJ 3708 [Density of Power Network 线路密度,a->b=b->a去重]
The vast power system is the most complicated man-made system and the greatest engineering innovatio ...
- Codeforces Round #306 (Div. 2) A. Two Substrings【字符串/判断所给的字符串中是否包含不重叠的“BA” “AB”两个字符串】
A. Two Substrings time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...
随机推荐
- 洛谷 P1341 无序字母对(欧拉路)
P1341 无序字母对 题目提供者yeszy 标签 福建省历届夏令营 难度 提高+/省选- 最新讨论 题目描述 给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒).请构造 ...
- 一步一步理解线段树——转载自JustDoIT
一步一步理解线段树 目录 一.概述 二.从一个例子理解线段树 创建线段树 线段树区间查询 单节点更新 区间更新 三.线段树实战 -------------------------- 一 概述 线段 ...
- 阿里云运行docker容器报错
[root@izbp145axkc98giot5b448z ~]# docker run -d 231d40e811cd -p 80:80 --name=nginx 56896ff0b49cfe5f1 ...
- [CSP-S模拟测试]:C(三分+贪心)
题目传送门(内部题46) 输入格式 第一行$3$个整数$n,m,t$.第二行$n$个整数,表示$P_i$.接下来$m$行每行两个整数,表示$L_i,R_i$. 输出格式 一行一个整数表示答案. 样例 ...
- legend3---6、legend3爬坑杂记
legend3---6.legend3爬坑杂记 一.总结 一句话总结: 学东西不做项目也学不到深处,其实也就是学了没理解透, 1.lavarel中模型关联可以用的实质是? lavarel在数据库中插入 ...
- Vue-1:鄙人是如何开始学习的
说实话,Vue这个东西早想学习她了.为啥呢?不是因为有多火热多好用多水嫩...而是每次面试都会问我,你会不会Vue...接下来就是突然安静的空气,,,真TM气人.所以鄙人在经历诸事之后决心一定要搞一下 ...
- CL_GUI_FRONTEND_SERVICES 使用问题
CL_GUI_FRONTEND_SERVICES(SAP操作Windows文件) 这个类下面的方法均为静态方法,引用的时候以=>来引用方法 注意:在执行CL_GUI_FRONTEND_SERVI ...
- Spring Data JPA 介绍
Spring-data-jpa的基本介绍:JPA诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,百度百科说是JDK为了实现ORM的天下归一,目前也是在按照这个方向发展,但是还没能完全实现.在 ...
- 如何优雅的给TDatetimePicker控件赋值(Delphi)
给DatetimePicker赋值时,可以通过界面设置赋值,也可以通过代码赋值. 通常,我们会给表示起始时间的dtp赋值为 00:00:00,给表示结束时间的dtp赋值为23:59:59. 代码如下: ...
- k8s开启cadvisor http 服务
k8s开启cadvisor http 服务 cadvisor介绍: Google的 cAdvisor 是另一个知名的开源容器监控工具. 只需在宿主机上部署cAdvisor容器,用户就可通过Web界面或 ...