传送门

思路

非常显然,就是要统计有多少种方式使得奇数的个数不超过\(n-2m\)。(考场上这个都没想到真是身败名裂了……)

考虑直接减去钦点\(n-2m+1\)个奇数之后的方案数,但显然这样会算重,所以考虑容斥。

设\(f_k\)表示至少有\(k\)个为奇数的方案数。

那么有

\[\begin{align*}
f_k&={D\choose k}{n!}[x^n](\frac{e^x-e^{-x}}{2})^k e^{(D-k)x}\\
&={D\choose k}\frac{1}{2^k}{n!}[x^n]({e^x-e^{-x}})^k e^{(D-k)x}
\end{align*}
\]

考虑后面的部分用二项式定理暴力拆开,得到

\[\begin{align*}
&[x^n]({e^x-e^{-x}})^k e^{(D-k)x}\\
=&[x^n]\sum_{i=0}^k {k\choose i}(-1)^{k-i}e^{ix}e^{-(k-i)x}e^{(D-k)x}\\
=&[x^n]\sum_{i=0}^k {k\choose i}(-1)^{k-i}e^{(D+2i-2k)x}\\
=&[x^n]\sum_{i=0}^k {k\choose i}(-1)^{i}e^{(D-2i)x}\\
=&\frac{1}{n!}\sum_{i=0}^k {k\choose i}(-1)^i(D-2i)^n
\end{align*}
\]

所以

\[f_k={D\choose k}\frac{1}{2^k}k!\sum_{i=0}^k \frac{(-1)^i(D-2i)^n}{i!}\frac{1}{(k-i)!}
\]

显然是一个卷积的形式,用NTT在\(O(D\log D)\)的时间内求出。

然后设\(g_k\)为恰好有\(k\)个奇数的方案数,有

\[f_k=\sum_{i=k}^D {i\choose k}g_i
\]

二项式反演得到

\[g_k=\sum_{i=k}^D (-1)^{i-k}{i\choose k}f_i
\]

显然也可以把组合数拆开之后NTT解决,复杂度同样\(O(D\log D)\)。

最后答案就是\(\sum_{i\le n-2m} g_i\),特判\(D\le n-2m\)时输出\(D^n\),就做完了。

代码

  1. #include<bits/stdc++.h>
  2. clock_t t=clock();
  3. namespace my_std{
  4. using namespace std;
  5. #define pii pair<int,int>
  6. #define fir first
  7. #define sec second
  8. #define MP make_pair
  9. #define rep(i,x,y) for (int i=(x);i<=(y);i++)
  10. #define drep(i,x,y) for (int i=(x);i>=(y);i--)
  11. #define go(x) for (int i=head[x];i;i=edge[i].nxt)
  12. #define templ template<typename T>
  13. #define sz 804040
  14. #define mod 998244353ll
  15. typedef long long ll;
  16. typedef double db;
  17. mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  18. templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
  19. templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
  20. templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
  21. templ inline void read(T& t)
  22. {
  23. t=0;char f=0,ch=getchar();double d=0.1;
  24. while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
  25. while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
  26. if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
  27. t=(f?-t:t);
  28. }
  29. template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
  30. char __sr[1<<21],__z[20];int __C=-1,__zz=0;
  31. inline void Ot(){fwrite(__sr,1,__C+1,stdout),__C=-1;}
  32. inline void print(register int x)
  33. {
  34. if(__C>1<<20)Ot();if(x<0)__sr[++__C]='-',x=-x;
  35. while(__z[++__zz]=x%10+48,x/=10);
  36. while(__sr[++__C]=__z[__zz],--__zz);__sr[++__C]='\n';
  37. }
  38. void file()
  39. {
  40. #ifdef NTFOrz
  41. freopen("a.in","r",stdin);
  42. #endif
  43. }
  44. inline void chktime()
  45. {
  46. #ifndef ONLINE_JUDGE
  47. cout<<(clock()-t)/1000.0<<'\n';
  48. #endif
  49. }
  50. #ifdef mod
  51. ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
  52. ll inv(ll x){return ksm(x,mod-2);}
  53. #else
  54. ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
  55. #endif
  56. // inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
  57. }
  58. using namespace my_std;
  59. int r[sz],limit;
  60. void NTT_init(int n)
  61. {
  62. limit=1;int l=-1;
  63. while (limit<=n+n) limit<<=1,++l;
  64. rep(i,0,limit-1) r[i]=(r[i>>1]>>1)|((i&1)<<l);
  65. }
  66. void NTT(ll *a,int type)
  67. {
  68. rep(i,0,limit-1) if (i<r[i]) swap(a[i],a[r[i]]);
  69. for (int mid=1;mid<limit;mid<<=1)
  70. {
  71. ll Wn=ksm(3,(mod-1)/mid>>1);if (type==-1) Wn=inv(Wn);
  72. for (int len=mid<<1,j=0;j<limit;j+=len)
  73. {
  74. ll w=1;
  75. for (int k=0;k<mid;k++,w=w*Wn%mod)
  76. {
  77. ll x=a[j+k],y=a[j+k+mid]*w%mod;
  78. a[j+k]=(x+y)%mod;a[j+k+mid]=(x-y+mod)%mod;
  79. }
  80. }
  81. }
  82. if (type==1) return;
  83. ll I=inv(limit);
  84. rep(i,0,limit-1) a[i]=a[i]*I%mod;
  85. }
  86. int D,n,m;
  87. ll fac[sz],_fac[sz];
  88. void init(){_fac[0]=fac[0]=1;rep(i,1,sz-1) _fac[i]=inv(fac[i]=fac[i-1]*i%mod);}
  89. ll tmp1[sz],tmp2[sz];
  90. ll f[sz],g[sz];
  91. void GetF()
  92. {
  93. rep(i,0,D) tmp1[i]=ksm(D-i*2,n)*_fac[i]%mod*((i&1)?mod-1:1ll)%mod;
  94. rep(i,0,D) tmp2[i]=_fac[i];
  95. NTT_init(D);
  96. NTT(tmp1,1);NTT(tmp2,1);
  97. rep(i,0,limit-1) tmp1[i]=tmp1[i]*tmp2[i]%mod;
  98. NTT(tmp1,-1);
  99. rep(i,0,D) f[i]=fac[D]*_fac[i]%mod*_fac[D-i]%mod*ksm(2,mod-1-i)%mod*fac[i]%mod*tmp1[i]%mod;
  100. rep(i,0,limit-1) tmp1[i]=tmp2[i]=0;
  101. }
  102. void GetG()
  103. {
  104. rep(i,0,D) tmp1[i]=f[i]*fac[i]%mod;
  105. rep(i,0,D) tmp2[i]=(((D-i)&1)?mod-1:1ll)*_fac[D-i]%mod;
  106. NTT_init(D+D);
  107. NTT(tmp1,1);NTT(tmp2,1);
  108. rep(i,0,limit-1) tmp1[i]=tmp1[i]*tmp2[i]%mod;
  109. NTT(tmp1,-1);
  110. rep(i,0,D) g[i]=_fac[i]*tmp1[D+i]%mod;
  111. rep(i,0,limit-1) tmp1[i]=tmp2[i]=0;
  112. }
  113. int main()
  114. {
  115. file();
  116. read(D,n,m);
  117. if (D<=n-2*m) return printf("%lld\n",ksm(D,n)),0;
  118. if (n<2*m) return puts("0"),0;
  119. init();
  120. GetF();GetG();
  121. ll ans=0;
  122. rep(i,0,n-2*m) (ans+=g[i])%=mod;
  123. cout<<ans;
  124. return 0;
  125. }

LOJ3120. 「CTS2019」珍珠 [容斥,生成函数]的更多相关文章

  1. 「CTS2019」珍珠

    「CTS2019」珍珠 解题思路 看了好多博客才会,问题即要求有多少种方案满足数量为奇数的变量数 \(\leq n-2m\).考虑容斥,令 \(F(k)\) 为恰好有 \(n\) 个变量数量为奇数的方 ...

  2. Solution -「CTS2019」珍珠

    题目   luogu. 题解   先 % 兔.同为兔子为什么小粉兔辣么强qwq. 本文大体跟随小粉兔的题解的思路,并为像我一样多项式超 poor 的读者作了很详细的解释.如果题解界面公式出现问题,可以 ...

  3. 「LOJ2091」「ZJOI2016」小星星 容斥+DP

    题目描述 小 Y 是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有\(n\)颗小星星,用 \(m\)条彩色的细线串了起来,每条细线连着两颗小星星.有一天她发现,她的饰品被破坏了,很多细线都被拆掉 ...

  4. [LOJ#3120][Luogu5401][CTS2019]珍珠(容斥+生成函数)

    https://www.luogu.org/blog/user50971/solution-p5401 #include<cstdio> #include<algorithm> ...

  5. 「CTS2019」氪金手游

    「CTS2019」氪金手游 解题思路 考场上想出了外向树的做法,居然没意识到反向边可以容斥,其实外向树会做的话这个题差不多就做完了. 令 \(dp[u][i]\) 表示单独考虑 \(u\) 节点所在子 ...

  6. LOJ#6503.「雅礼集训 2018 Day4」Magic[容斥+NTT+启发式合并]

    题意 \(n\) 张卡牌 \(m\) 种颜色,询问有多少种本质不同的序列满足相邻颜色相同的位置数量等于 \(k\). 分析 首先本质不同不好直接处理,可以将同种颜色的卡牌看作是不相同的,求出答案后除以 ...

  7. bzoj3771: Triple(容斥+生成函数+FFT)

    传送门 咳咳忘了容斥了-- 设\(A(x)\)为斧头的生成函数,其中第\(x^i\)项的系数为价值为\(i\)的斧头个数,那么\(A(x)+A^2(x)+A^3(x)\)就是答案(于是信心满满的打了一 ...

  8. 【洛谷5644】[PKUWC2018] 猎人杀(容斥+生成函数+分治NTT)

    点此看题面 大致题意: 有\(n\)个人相互开枪,每个人有一个仇恨度\(a_i\),每个人死后会开枪再打死另一个还活着的人,且第一枪由你打响.设当前剩余人仇恨度总和为\(k\),则每个人被打中的概率为 ...

  9. 5.15 省选模拟赛 容斥 生成函数 dp

    LINK:5.15 T2 个人感觉生成函数更无脑 容斥也好推的样子. 容易想到每次放数和数字的集合无关 所以得到一个dp f[i][j]表示前i个数字 逆序对为j的方案数. 容易得到转移 使用前缀和优 ...

随机推荐

  1. jacascript Date 学习

    前言:这是笔者学习之后自己的理解与整理.如果有错误或者疑问的地方,请大家指正,我会持续更新! Date dateObject.getDate();  返回一个月中的某一天(1-31) dateObje ...

  2. (三)XML基础(3):Xpath

    五.XPath:快速定位到节点 5.1 简介 5.2 语法 5.3 案例 XPath对有命名空间的xml文件和没有命名空间的xml定位节点的方法是不一样的,所以再对不同的xml需要进行不同的处理. 使 ...

  3. C#获取Excel表格所有sheet名(Epplus)

    原文:C#获取Excel表格所有sheet名(Epplus) 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...

  4. datagrid使用和文字超出tip提示

    function LoadTable(queryData) {             $("#eventInfoTable").datagrid({               ...

  5. kong网关命令(一)

    上次在虚拟机里安装kong网关后,因为版本(1.4)太高,目前Kong Dashboard无法支持, 后续发现Git上有个开源工具Kong admin ui,下载源码并部署到NGINX. 但是发现使用 ...

  6. iOS热更新实现方式

    heart.jpg 苹果静止热更新,可惜我的是企业app,没有这些约束了,随便用.(当然有些热更新已经可以通过苹果审核了,比如JSPatch)官网说的: JSPatch 平台 SDK 1.7.2 以上 ...

  7. 如何在SAP Kyma的控制台里扩展新的UI

    方法是创建一个新的resource,类型为ClusterMicroFrontend. 使用命令行kubectl get ClusterMicroFrontend查看这些UI扩展: 最后自定义的UI出现 ...

  8. swoole深入学习 8. 协程 转

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/yangyi2083334/article/ ...

  9. flask 反向解析示例

    1 静态网页 和动态网页 1 静态网页:无法与服务器做动态交互的网页 2 动态网页:允许与服务器做动态加护的 2 WEB 与 服务器 1 WEB :网页(HTML,css,JS) 3 服务器的作用: ...

  10. 【Intel 汇编】ELF文件

    ELF文件格式是一个开放标准,各种UNIX系统的可执行文件都采用ELF格式,它有三种不同的类型: 可重定位的目标文件(Relocatable,或者Object File) 可执行文件(Executab ...