IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 【luogu P5339】唱、跳、rap和篮球(容斥)(NTT)(OGF) -> 正文阅读

[数据结构与算法]【luogu P5339】唱、跳、rap和篮球(容斥)(NTT)(OGF)

唱、跳、rap和篮球

题目链接:luogu P5339

题目大意

给你 a,b,c,d 四个字符的个数,然后问你可以组成多少个长度为 n 的字符串使得没有 abcd 这个子串。

思路

考虑容斥,用至少 0 0 0 a b c d abcd abcd 子串减去至少 1 1 1 a b c d abcd abcd 子串加上两个的……

然后考虑怎么排这些子串,可以发现这些子串不可能重叠(毕竟都是不同的),那我们可以把它看做一个整体 e e e
那我们就变成了如果是至少 i i i 个,这些摆的方案数就是 ( n ? 3 i i ) \binom{n-3i}{i} (in?3i?)
? 3 i -3i ?3i 就相当于你把原本长度为四的 a b c d abcd abcd 压缩为 e e e,每个少了三个字符,然后你就随便选 i i i 个位置放 e e e

然后你接着考虑剩下的位置怎么随便放。
那不难想出它可以用一般生成函数 OGF 的思想来搞。
那我们考虑乘起来的四个多项式要如何构造。
考虑用有相同元素的排列数 n ! n 1 ! n 2 ! . . . \dfrac{n!}{n_1!n_2!...} n1?!n2?!...n!?

那我们四个多项式可以构造为形如 1 a ! , 1 a ! , . . . , 1 a ! , 0 , 0 , . . . \dfrac{1}{a!},\dfrac{1}{a!},...,\dfrac{1}{a!},0,0,... a!1?,a!1?,...,a!1?,0,0,... 的形式。
(其中 1 a ! \dfrac{1}{a!} a!1? 的最高项位置就是它能放的 a a a 个数, b c d bcd bcd 同理)
然后前面乘上一个 ( n ? 3 i ) ! (n-3i)! (n?3i)! 就是每个的答案了。

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#define mo 998244353

using namespace std;

int n, a, b, c, d, ans, di, m;
int jc[20001], inv[20001], G, Gv;
int limit, l_size, an[20001];
int A[20001], B[20001], C[20001], D[20001];

int jia(int x, int y) {
	return (x + y >= mo) ? x + y - mo : x + y;
}

int jian(int x, int y) {
	return (x < y) ? (x - y + mo) : (x - y);
}

int cheng(int x, int y) {
	return 1ll * x * y % mo;
}

int CC(int n, int m) {
	if (m < 0 || m > n) return 0;
	return cheng(jc[n], cheng(inv[m], inv[n - m]));
}

int ksm(int x, int y) {
	int re = 1;
	while (y) {
		if (y & 1) re = cheng(re, x);
		x = cheng(x, x); y >>= 1;
	}
	return re;
}

void NTT(int *f, int op) {
	for (int i = 0; i < limit; i++)
		if (i < an[i]) swap(f[i], f[an[i]]);
	for (int mid = 1; mid < limit; mid <<= 1) {
		int Wn = ksm((op == 1) ? G : Gv, (mo - 1) / (mid << 1));
		for (int R = (mid << 1), j = 0; j < limit; j += R) {
			int w = 1;
			for (int k = 0; k < mid; k++, w = cheng(w, Wn)) {
				int x = f[j + k], y = cheng(w, f[j + mid + k]);
				f[j + k] = jia(x, y); f[j + mid + k] = jian(x, y);
			}
		}
	}
	if (op == -1) {
		int invl = ksm(limit, mo - 2);
		for (int i = 0; i < limit; i++) f[i] = cheng(f[i], invl);
	}
}

int P(int n, int a, int b, int c, int d) {
	if (n < 0 || a + b + c + d < n) return 0;
	limit = 1; l_size = 0;
	while (limit <= (a + b + c + d) * 2) {
		limit <<= 1; l_size++;
	}
	for (int i = 0; i < limit; i++)
		an[i] = (an[i >> 1] >> 1) | ((i & 1) << (l_size - 1));
	
	for (int i = 0; i < limit; i++) {
		A[i] = (i <= a) ? inv[i] : 0;
		B[i] = (i <= b) ? inv[i] : 0;
		C[i] = (i <= c) ? inv[i] : 0;
		D[i] = (i <= d) ? inv[i] : 0; 
	}
	NTT(A, 1); NTT(B, 1); NTT(C, 1); NTT(D, 1);
	for (int i = 0; i < limit; i++)
		A[i] = cheng(cheng(A[i], B[i]), cheng(C[i], D[i]));
	NTT(A, -1);
	
	return cheng(jc[n], A[n]);
}

int main() {
	G = 3; Gv = ksm(G, mo - 2);
	jc[0] = 1; for (int i = 1; i <= 20000; i++) jc[i] = cheng(jc[i - 1], i);
	inv[0] = inv[1] = 1; for (int i = 2; i <= 20000; i++) inv[i] = cheng(inv[mo % i], mo - mo / i);
	for (int i = 1; i <= 20000; i++) inv[i] = cheng(inv[i - 1], inv[i]);
	
	scanf("%d %d %d %d %d", &n, &a, &b, &c, &d);
	m = min(min(a, b), min(c, d));
	
	ans = 0; di = 1;
	for (int i = 0; i <= m; i++) {
		ans = jia(ans, cheng(cheng(di, CC(n - 3 * i, i)), P(n - 4 * i, a - i, b - i, c - i, d - i)));
		di = mo - di;
	}
	printf("%d", ans);
	
	return 0;
}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-01-28 12:10:13  更:2022-01-28 12:11:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 19:36:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码