题面传送门

一道多项式的 hot tea

首先考虑将题目的限制翻译成人话,我们记 \(c_i\) 为 \(i\) 的出现次数,那么题目的限制等价于 \(\sum\limits_{i=1}^D\lfloor\dfrac{c_i}{2}\rfloor\le m\)。不难发现这里涉及下取整,稍微有些棘手,因此考虑将这个下取整去掉,显然 \(\lfloor\dfrac{c_i}{2}\rfloor=\dfrac{c_i-c_i\bmod 2}{2}\),故原式可化为 \(\sum\limits_{i=1}^D\dfrac{c_i-c_i\bmod 2}{2}\le m\),我们将左右两边同乘 \(2\),再稍微变个形可得 \(\sum\limits_{i=1}^Dc_i-\sum\limits_{i=1}^Dc_i\bmod 2\le 2m\),显然 \(\sum\limits_{i=1}^Dc_i=n\),故 \(\sum\limits_{i=1}^Dc_i\bmod 2\le n-2m\),也就是 \(c\) 数组中奇数个数 \(\le n-2m\)

方便起见我们先特判掉 \(n-2m<0\) 和 \(n-2m\ge D\) 的情况,两种情况的答案分别为 \(0\) 和 \(D^n\)。接下来我们着重考虑 \(0\le n-2m\lt D\) 的情况。我们记 \(f_i\) 为 \(c\) 数列中恰好存在 \(i\) 个奇数的方案数,那么答案即为 \(\sum\limits_{i=0}^{n-2m}f_i\),注意到这个“恰好 \(i\) 个”很棘手,因此按照套路设 \(g_i\) 表示钦定 \(i\) 个 \(c_j\) 为奇数,剩余随便排的方案数,求出 \(g_i\) 后即可二项式反演求出 \(f_i\),即 \(f_i=\sum\limits_{j=i}\dbinom{j}{i}(-1)^{j-i}g_j\),把式子稍微转化一下即可得到 \(f_i=\dfrac{1}{i!}\sum\limits_{j}j!g_j\times(-1)^{j-i}\dfrac{1}{(j-i)!}\),这显然是一个差卷积的形式,因此求出 \(g_i\) 之后一遍差卷积即可求出答案了。

接下来我们的任务就是求出 \(g_i\)。首先我们肯定要从 \(D\) 种数中选出 \(i\) 个并钦定它们出现次数为奇数,这样选的方案数为 \(\dbinom{D}{i}\)。其次,注意到求出每个数的出现次数后求原序列的方案数是一个二项加法卷积,因此考虑 EGF,根据生成函数那一套理论,我们钦定出现次数为奇数的 EGF 为 \(\dfrac{e^x-e^{-x}}{2}\),其余没有限制的数的 EGF 为 \(e^x\),故 \(g_i=\dbinom{D}{i}n![x^n](\dfrac{e^x-e^{-x}}{2})^i(e^x)^{D-i}\),我们考虑用二项式定理展开并将其变个形,则可以得到:

\[\begin{aligned}
g_i&=\dbinom{D}{i}n![x^n](\dfrac{e^x-e^{-x}}{2})^i(e^x)^{D-i}\\
&=\dbinom{D}{i}\dfrac{n!}{2^i}[x^n](e^x-e^{-x})^i(e^x)^{D-i}\\
&=\dbinom{D}{i}\dfrac{n!}{2^i}[x^n]\sum\limits_{j=0}^i\dbinom{i}{j}(e^x)^j(-e^{-x})^{i-j}(e^x)^{D-i}\\
&=\dbinom{D}{i}\dfrac{n!}{2^i}[x^n]\sum\limits_{j=0}^i\dbinom{i}{j}(e^x)^j(e^{-x})^{i-j}(e^x)^{D-i}(-1)^{i-j}\\
&=\dbinom{D}{i}\dfrac{n!}{2^i}[x^n]\sum\limits_{j=0}^i\dbinom{i}{j}(e^x)^{D-2(i-j)}(-1)^{i-j}\\
&=\dbinom{D}{i}\dfrac{n!}{2^i}\sum\limits_{j=0}^i\dbinom{i}{j}[x^n](e^x)^{D-2(i-j)}(-1)^{i-j}\\
&=\dbinom{D}{i}\dfrac{n!}{2^i}\sum\limits_{j=0}^i\dbinom{i}{j}\dfrac{1}{n!}(D-2(i-j))^n(-1)^{i-j}\\
&=\dbinom{D}{i}\dfrac{1}{2^i}\sum\limits_{j=0}^i\dfrac{i!}{j!(i-j)!}(D-2(i-j))^n(-1)^{i-j}\\
&=\dbinom{D}{i}\dfrac{1}{2^i}i!\sum\limits_{j=0}^i\dfrac{1}{j!}·\dfrac{(D-2(i-j))^n(-1)^{i-j}}{(i-j)!}
\end{aligned}
\]

推到这一步不难发现这是一个卷积的形式,记 \(a_j=\dfrac{1}{j!},b_j=\dfrac{(D-2j)^n(-1)^{j}}{j!}\),跑遍卷积即可求出 \(g_i\)

时间复杂度 \(D\log D\)。

const int MAXP=1<<18;
const int MOD=998244353;
const int pr=3;
const int ipr=(MOD+1)/3;
const int INV2=MOD+1>>1;
int qpow(int x,int e){
int ret=1;
for(;e;e>>=1,x=1ll*x*x%MOD) if(e&1) ret=1ll*ret*x%MOD;
return ret;
}
int D,n,m,fac[MAXP+5],ifac[MAXP+5];
void init_fac(int n){
for(int i=(fac[0]=ifac[0]=ifac[1]=1)+1;i<=n;i++) ifac[i]=1ll*ifac[MOD%i]*(MOD-MOD/i)%MOD;
for(int i=1;i<=n;i++) fac[i]=1ll*fac[i-1]*i%MOD,ifac[i]=1ll*ifac[i-1]*ifac[i]%MOD;
}
int binom(int n,int k){return 1ll*fac[n]*ifac[k]%MOD*ifac[n-k]%MOD;}
int rev[MAXP+5];
void NTT(vector<int> &a,int len,int type){
int lg=31-__builtin_clz(len);
for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
for(int i=0;i<len;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int i=2;i<=len;i<<=1){
int W=qpow((type<0)?ipr:pr,(MOD-1)/i);
for(int j=0;j<len;j+=i){
for(int k=0,w=1;k<(i>>1);k++,w=1ll*w*W%MOD){
int X=a[j+k],Y=1ll*a[(i>>1)+j+k]*w%MOD;
a[j+k]=(X+Y)%MOD;a[(i>>1)+j+k]=(X-Y+MOD)%MOD;
}
}
}
if(type==-1){
int ivn=qpow(len,MOD-2);
for(int i=0;i<len;i++) a[i]=1ll*a[i]*ivn%MOD;
}
}
vector<int> conv(vector<int> a,vector<int> b){
int LEN=1;while(LEN<a.size()+b.size()) LEN<<=1;
a.resize(LEN,0);b.resize(LEN,0);NTT(a,LEN,1);NTT(b,LEN,1);
for(int i=0;i<LEN;i++) a[i]=1ll*a[i]*b[i]%MOD;
NTT(a,LEN,-1);return a;
}
int main(){
scanf("%d%d%d",&D,&n,&m);init_fac(D);
if(n-2*m>=D) return printf("%d\n",qpow(D,n)),0;
if(n-2*m<0) return printf("0\n"),0;
vector<int> a(D+1),b(D+1);
for(int i=0;i<=D;i++){
a[i]=ifac[i];
if(i&1) b[i]=(MOD-1ll*qpow((D-2*i+MOD)%MOD,n)*ifac[i]%MOD)%MOD;
else b[i]=1ll*qpow((D-2*i+MOD)%MOD,n)*ifac[i]%MOD;
}
vector<int> f=conv(a,b),h(D+1);f.resize(D+1);
for(int i=0,pw=1;i<=D;i++,pw=1ll*pw*INV2%MOD)
f[i]=1ll*f[i]*binom(D,i)%MOD*pw%MOD*fac[i]%MOD;
for(int i=0;i<=D;i++) f[i]=1ll*f[i]*fac[i]%MOD;
for(int i=0;i<=D;i++){
if(i&1) h[D-i]=MOD-ifac[i];
else h[D-i]=ifac[i];
} vector<int> g=conv(f,h);int ans=0;
for(int i=0;i<=n-2*m;i++) ans=(ans+1ll*g[D+i]*ifac[i])%MOD;
printf("%d\n",ans);
return 0;
}

洛谷 P5401 - [CTS2019]珍珠(NTT+二项式反演)的更多相关文章

  1. 洛谷 P5400 - [CTS2019]随机立方体(组合数学+二项式反演)

    洛谷题面传送门 二项式反演好题. 首先看到"恰好 \(k\) 个极大值点",我们可以套路地想到二项式反演,具体来说我们记 \(f_i\) 为钦定 \(i\) 个点为极大值点的方案数 ...

  2. LOJ 3120: 洛谷 P5401: 「CTS2019 | CTSC2019」珍珠

    题目传送门:LOJ #3120. 题意简述: 称一个长度为 \(n\),元素取值为 \([1,D]\) 的整数序列是合法的,当且仅当其中能够选出至少 \(m\) 对相同元素(不能重复选出元素). 问合 ...

  3. 洛谷 P5518 - [MtOI2019]幽灵乐团 / 莫比乌斯反演基础练习题(莫比乌斯反演+整除分块)

    洛谷题面传送门 一道究极恶心的毒瘤六合一题,式子推了我满满两面 A4 纸-- 首先我们可以将式子拆成: \[ans=\prod\limits_{i=1}^A\prod\limits_{j=1}^B\p ...

  4. 题解 P5401 [CTS2019]珍珠

    蒟蒻语 这题太玄学了,蒟蒻写篇题解来让之后复习 = = 蒟蒻解 假设第 \(i\) 个颜色有 \(cnt_i\) 个珍珠. \(\sum\limits_{i=1}^{n} \left\lfloor\f ...

  5. 洛谷P2257 YY的GCD 莫比乌斯反演

    原题链接 差不多算自己推出来的第一道题QwQ 题目大意 \(T\)组询问,每次问你\(1\leqslant x\leqslant N\),\(1\leqslant y\leqslant M\)中有多少 ...

  6. [洛谷P1390]公约数的和·莫比乌斯反演

    公约数的和 传送门 分析 这道题很显然答案为 \[Ans=\sum_{i=1}^n\sum_{j=i+1}^n (i,j)\] //其中\((i,j)\)意味\(gcd(i,j)\) 这样做起来很烦, ...

  7. 洛谷 - P4449 - 于神之怒加强版 - 莫比乌斯反演

    https://www.luogu.org/problemnew/show/P4449 \(F(n)=\sum\limits_{i=1}^{n}\sum\limits_{i=1}^{m} gcd(i, ...

  8. 洛谷 - SP3871 GCDEX - GCD Extreme - 莫比乌斯反演

    易得 $\sum\limits_{g=1}^{n} g \sum\limits_{k=1}^{n} \mu(k) \lfloor\frac{n}{gk}\rfloor \lfloor\frac{n}{ ...

  9. 洛谷 - P1390 - 公约数的和 - 莫比乌斯反演 - 欧拉函数

    https://www.luogu.org/problemnew/show/P1390 求 $\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m} gcd(i,j) $ ...

随机推荐

  1. Android构建工具--AAPT2源码解析(一)

    一.什么是AAPT2 在Android开发过程中,我们通过Gradle命令,启动一个构建任务,最终会生成构建产物"APK"文件.常规APK的构建流程如下: (引用自Google官方 ...

  2. 改善深层神经网络-week2编程题(Optimization Methods)

    1. Optimization Methods Gradient descent goes "downhill" on a cost function \(J\). Think o ...

  3. Coursera Deep Learning笔记 结构化机器学习项目 (下)

    参考:https://blog.csdn.net/red_stone1/article/details/78600255https://blog.csdn.net/red_stone1/article ...

  4. Java:ThreadLocal小记

    Java:ThreadLocal小记 说明:这是看了 bilibili 上 黑马程序员 的课程 java基础教程由浅入深全面解析threadlocal 后做的笔记 内容 ThreadLocal 介绍 ...

  5. UltraSoft - Beta - Scrum Meeting 4

    Date: May 20th, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 完成了课程中心对课程提醒的爬虫 Liuzh 前端 修改DDL列表中起始时间为课程名 ...

  6. spring security中ajax超时处理

    spring security为我们的系统提供了方便的认证和授权操作.在系统中完成认证和授权后,一般页面页面上大多数是ajax和后台进行操作,那么这个时候可能就会面临session超时,ajax去访问 ...

  7. Python触发异常

    我们可以使用raise语句自己触发异常,raise语法格式如下: raise [Exception [, args [, traceback]]] 语句中 Exception 是异常的类型(例如,Na ...

  8. The entitlements specified in your application’s Code Signing Entitlements file do not match those s

    今天给打包 TPshop IOS (搜豹商城) ipa文件 调试运行 xcode运行提示这个错误: The entitlements specified in your application's C ...

  9. 【行人惯性导航】关于行人导航中IMU位姿推导的知识点及相关代码

    IMU姿态惯性推导 最近从事行人惯性导航的研究,本人也是一个小白,其中看了很多文献,有很多个人思考很费时间的地方,撰写此随笔的目的不仅是给自己做一个笔记,也是给各位有需要的仁兄一点个人理解. 本文只关 ...

  10. [转]DDR3基本概念5 - DDR仿真中出现的Memory overflow错误的处理

    ERROR: Memory overflow. Write to Address 7000fe with data xxxxxxxxxxxxxxxx4634899aabe03499 will be l ...