「CTS2019」珍珠
「CTS2019」珍珠
解题思路
看了好多博客才会,问题即要求有多少种方案满足数量为奇数的变量数 \(\leq n-2m\)。考虑容斥,令 \(F(k)\) 为恰好有 \(n\) 个变量数量为奇数的方案数,\(G(k)\) 为钦点了 \(k\) 种变量的选法且它们数量都是奇数,剩下的变量随便组合的方案数。
那么,
\]
显然 \(F, G\) 之间满足以下关系:
F(k) =\sum_{i=k}^D {i\choose k}(-1)^{i-k}G(i)
\]
第二个式子是一个经典卷积,所以只要求出 \(G\) 做多项式乘法就可以快速得到答案了。
考虑钦点的变量是有标号集合的拼接,用指数型生成函数 \(\frac{e^{x}-e^{-x}}{2}\) 的形式表示单个变量数量为奇数的选法,\(e^x\) 表示剩下变量随便选的选法,于是
=[x^n]\frac{1}{2^k}{D \choose k}(e^x-e^{-x})^ke^{x(D-k)}
\]
二项式展开可以得到
=[x^n]\frac{1}{2^k}{D \choose k}\sum_{i=0}^k{k \choose i}(-1)^ie^{x(D-2i)} \\
=\frac{1}{2^k}{D \choose k}\sum_{i=0}^k{k \choose i}(-1)^i(D-2i)^n
\]
发现是一个卷积的形式,也只需要一遍多项式乘法。
code
/*program by mangoyang*/
#include <bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1 << 19, mod = 998244353, G = 3;
int a[N], b[N], js[N], inv[N], n, m, D, ans;
namespace poly{
int rev[1<<22], len, lg;
inline int Pow(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 timesinit(int lenth){
for(len = 1, lg = 0; len <= lenth; len <<= 1, lg++);
for(int i = 0; i < len; i++)
rev[i] = (rev[i>>1] >> 1) | ((i & 1) << (lg - 1));
}
inline void dft(int *a, int sgn){
for(int i = 0; i < len; i++)
if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int k = 2; k <= len; k <<= 1){
int w = Pow(G, (mod - 1) / k);
if(sgn == -1) w = Pow(w, mod - 2);
for(int i = 0; i < len; i += k){
int now = 1;
for(int j = i; j < i + (k >> 1); j++){
int x = a[j], y = 1ll * a[j+(k>>1)] * now % mod;
a[j] = x + y >= mod ? x + y - mod : x + y;
a[j+(k>>1)] = x - y < 0 ? x - y + mod : x - y;
now = 1ll * now * w % mod;
}
}
}
if(sgn == -1){
int Inv = Pow(len, mod - 2);
for(int i = 0; i < len; i++) a[i] = 1ll * a[i] * Inv % mod;
}
}
}
using poly::timesinit;
using poly::Pow;
using poly::dft;
int main(){
read(D), read(n), read(m);
js[0] = 1, inv[0] = 1;
for(int i = 1; i <= D; i++){
js[i] = 1ll * js[i-1] * i % mod;
inv[i] = Pow(js[i], mod - 2);
}
for(int i = 0; i <= D; i++){
a[i] = 1ll * inv[i] * Pow((D - 2 * i + mod) % mod, n) % mod;
if(i & 1) a[i] = mod - a[i];
b[i] = inv[i];
}
timesinit(D + D + 1);
dft(a, 1), dft(b, 1);
for(int i = 0; i < poly::len; i++)
a[i] = 1ll * a[i] * b[i] % mod;
dft(a, -1);
for(int i = D + 1; i < poly::len; i++) a[i] = 0;
for(int i = 0; i <= D; i++){
a[i] = 1ll * a[i] * Pow(Pow(2, i), mod - 2) % mod;
a[i] = 1ll * a[i] * js[D] % mod * inv[i] % mod * inv[D-i] % mod;
a[i] = 1ll * a[i] * js[i] % mod;
a[i] = 1ll * a[i] * js[i] % mod;
if(i & 1) a[i] = (mod - a[i]) % mod;
}
reverse(a, a + D + 1);
dft(a, 1);
for(int i = 0; i < poly::len; i++)
a[i] = 1ll * a[i] * b[i] % mod;
dft(a, -1);
for(int i = 0; i <= min(n - 2 * m, D); i++){
int x = 1ll * a[D-i] * inv[i] % mod;
if(i & 1) x = (mod - x) % mod;
ans = (ans + x) % mod;
}
cout << ans << endl;
return 0;
}
「CTS2019」珍珠的更多相关文章
- LOJ3120. 「CTS2019」珍珠 [容斥,生成函数]
传送门 思路 非常显然,就是要统计有多少种方式使得奇数的个数不超过\(n-2m\).(考场上这个都没想到真是身败名裂了--) 考虑直接减去钦点\(n-2m+1\)个奇数之后的方案数,但显然这样会算重, ...
- Solution -「CTS2019」珍珠
题目 luogu. 题解 先 % 兔.同为兔子为什么小粉兔辣么强qwq. 本文大体跟随小粉兔的题解的思路,并为像我一样多项式超 poor 的读者作了很详细的解释.如果题解界面公式出现问题,可以 ...
- 「CTS2019」氪金手游
「CTS2019」氪金手游 解题思路 考场上想出了外向树的做法,居然没意识到反向边可以容斥,其实外向树会做的话这个题差不多就做完了. 令 \(dp[u][i]\) 表示单独考虑 \(u\) 节点所在子 ...
- Loj #3124. 「CTS2019 | CTSC2019」氪金手游
Loj #3124. 「CTS2019 | CTSC2019」氪金手游 题目描述 小刘同学是一个喜欢氪金手游的男孩子. 他最近迷上了一个新游戏,游戏的内容就是不断地抽卡.现在已知: - 卡池里总共有 ...
- 「CTS2019 | CTSC2019」氪金手游 解题报告
「CTS2019 | CTSC2019」氪金手游 降 智 好 题 ... 考场上签到失败了,没想容斥就只打了20分暴力... 考虑一个事情,你抽中一个度为0的点,相当于把这个点删掉了(当然你也只能抽中 ...
- 「CTS2019 | CTSC2019」随机立方体 解题报告
「CTS2019 | CTSC2019」随机立方体 据说这是签到题,但是我计数学的实在有点差,这里认真说一说. 我们先考虑一些事实 如果我们在位置\((x_0,y_0,z_0)\)钦定了一个极大数\( ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
随机推荐
- 【loj3123】【CTS2019】重复
题目 给出一个长度为\(n\)的串\(s\),询问有多少个长度为\(m\)的串\(t\) 满足 \(t\) 的无限循环串存在一个长度为\(n\)且比\(s\)字典序严格小的子串 $ n , m \le ...
- shell脚本编程之变量的小用法
变量赋值 ${parameter:-word}:如果parameter为空或未定义,则变量展开为"word":否则,展开为parameter的值: ${parameter:+wor ...
- JVM内存的划分
JVM内存的划分有五片: 1. 寄存器: 2. 本地方法区: 3. 方法区: 4. 栈内存: 5. 堆内存.
- mysql 添加表字段
mysql> alter table table1 add price ) not null; Query OK, rows affected (0.05 sec) Records: Dupli ...
- 【数值分析】Python实现Lagrange插值
一直想把这几个插值公式用代码实现一下,今天闲着没事,尝试尝试. 先从最简单的拉格朗日插值开始!关于拉格朗日插值公式的基础知识就不赘述,百度上一搜一大堆. 基本思路是首先从文件读入给出的样本点,根据输入 ...
- 剑指offer:两个链表的第一个公共结点
题目描述: 输入两个链表,找出它们的第一个公共结点. 解题思路: 这道题一开始的题意不太理解,这里的公共结点,实际上指结点指相同,在题目不存在结点值相同的不同结点. 1. 最直接的思路是对链表一的每个 ...
- visual studio 无添加视图 选项
我是因为 UserController未继承 Controller
- Python3基础 yield send 获得生成器后,需要先启动一次
Python : 3.7.3 OS : Ubuntu 18.04.2 LTS IDE : pycharm-community-2019.1.3 ...
- osg::Node源码
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source ...
- 筛选出dataframe中全为数字的列的值
In [1]: import pandas as pd In [2]: import numpy as np In [3]: students = [ ('jack', 'Apples' , 34) ...