LINK:优雅的绽放吧,墨染樱花



当时考完只会50分的做法 最近做了某道题受到启发 故会做这道题目了。(末尾附30分 50分 100分code

看到度数容易想到prufer序列 考虑dp统计方案数。

设f[i][j]表示前i个数字占了prufer序列j个位置的方案数.最后答案为f[n][n-2].

容易想到转移 \(f[i][j]+=f[i-1][k]\cdot C(n-k,j-k)\cdot w_i^{j-k+1}\cdot (j-k+1)\)

复杂度n^3 期望得分30.

容易发现第二维是一个卷积 NTT优化 复杂度n^2log 期望得分50.

考虑满分做法:若知道一个度数排列 满足\(\sum_i d_i=n-2\)

那么容易计算出贡献. 贡献为\(\frac{(n-2)!}{\Pi (d_i!)}\Pi (d_i+1)w_i^{d_i+1}\)

考虑对于这个式子先进行化简:\((n-2)!\Pi w_i\frac{1}{\Pi (d_i!)}\Pi (d_i+1)w_i^{d_i}\)

那么前面是一个常数 考虑对后面的式子进行变形.

由于存在阶乘 考虑设出EGF来解决问题。

对于第i个点 设F(x)为其贡献的EGF. \(F(x)=\sum_{j=0}^{\infty}\frac{w_i^{j}x^j(j+1)}{j!}\)

那么我们要求的就是 \([x^{n-2}]\Pi F(x_i)\)

直接求复杂度还是n^2log 这个连乘很麻烦 考虑化简.

考虑取对数 然后再exp回来 逐个取复杂度还是很高。

一个trick 设\(G(x)=\sum_{j=0}^{\infty}\frac{x^j(j+1)}{j!}\)

那么对G(x)取对数后对应项乘以 \(w_i^k\) 那么和刚才的F(x)取对数等价。

关键如何求\(\sum_{k=0}\sum_{i=1}^n w_i^k\)

还是设出上式的生成函数W(x) 容易得到\(W(x)=\sum_{i=1}^n\frac{1}{1-w_ix}\)

\(W(x)=\sum_{i=1}^n1-\frac{w_ix}{1-w_ix}\)

一个trick \([Ln(1-w_ix)]'=-\frac{w_i}{1-w_ix}\)

此时有 \(W(x)=n-x\sum_{i=1}^n(Ln(1-w_ix))\)

那么存在\(W(x)=n-x(Ln(\Pi_{}^n(1-w_ix)))'\)

里面那个东西可以直接分治NTT求.

综上分为两部 前者nlogn 后者 nlog^2. 期望得分100.

  1. score 30
  2. const int MAXN=5010;
  3. int n;
  4. int w[MAXN],fac[MAXN],inv[MAXN];
  5. int f[MAXN][MAXN];//f[i][j]表示前i个数填了j个位置的贡献.
  6. inline int ksm(int b,int p)
  7. {
  8. int cnt=1;
  9. while(p){if(p&1)cnt=(ll)cnt*b%mod;p=p>>1;b=(ll)b*b%mod;}
  10. return cnt;
  11. }
  12. inline int C(int a,int b){if(a<b)return 0;return (ll)fac[a]*inv[b]%mod*inv[a-b]%mod;}
  13. int main()
  14. {
  15. freopen("yuyuko.in","r",stdin);
  16. freopen("yuyuko.out","w",stdout);
  17. get(n);fac[0]=1;
  18. rep(1,n,i)get(w[i]),fac[i]=(ll)fac[i-1]*i%mod;
  19. inv[n]=ksm(fac[n],mod-2);
  20. fep(n-1,0,i)inv[i]=(ll)inv[i+1]*(i+1)%mod;
  21. f[0][0]=1;
  22. rep(1,n,i)
  23. {
  24. rep(0,n-2,j)
  25. {
  26. int ww=1;
  27. rep(1,j+1,k)
  28. {
  29. ww=(ll)ww*w[i]%mod;
  30. f[i][j]=(f[i][j]+(ll)f[i-1][j-k+1]*C(n-2-j+k-1,k-1)%mod*k%mod*ww)%mod;
  31. }
  32. }
  33. }
  34. put(f[n][n-2]);
  35. return 0;
  36. }
  37. score 50
  38. const int MAXN=200010,G=3;
  39. int n,lim,INV;
  40. int w[MAXN],rev[MAXN],fac[MAXN],inv[MAXN];
  41. int f[MAXN],g[MAXN],c[MAXN];//f[i][j]表示前i个数填了j个位置的贡献.
  42. inline int ksm(int b,int p)
  43. {
  44. int cnt=1;
  45. while(p){if(p&1)cnt=(ll)cnt*b%mod;p=p>>1;b=(ll)b*b%mod;}
  46. return cnt;
  47. }
  48. inline int C(int a,int b){if(a<b)return 0;return (ll)fac[a]*inv[b]%mod*inv[a-b]%mod;}
  49. inline void NTT(int *a,int op)
  50. {
  51. rep(1,lim-1,i)if(i<rev[i])swap(a[i],a[rev[i]]);
  52. for(int len=2;len<=lim;len=len<<1)
  53. {
  54. int mid=len>>1;
  55. int wn=ksm(G,op==1?(mod-1)/len:mod-1-(mod-1)/len);
  56. for(int j=0;j<lim;j+=len)
  57. {
  58. int d=1;
  59. for(int i=0;i<mid;++i)
  60. {
  61. int x=a[i+j],y=(ll)a[i+j+mid]*d%mod;
  62. a[i+j]=(x+y)%mod;a[i+j+mid]=(x-y+mod)%mod;
  63. d=(ll)d*wn%mod;
  64. }
  65. }
  66. }
  67. }
  68. int main()
  69. {
  70. freopen("yuyuko.in","r",stdin);
  71. freopen("yuyuko.out","w",stdout);
  72. get(n);fac[0]=1;f[0]=1;
  73. rep(1,n,i)get(w[i]),fac[i]=(ll)fac[i-1]*i%mod;
  74. inv[n]=ksm(fac[n],mod-2);
  75. fep(n-1,0,i)inv[i]=(ll)inv[i+1]*(i+1)%mod;
  76. lim=1;while(lim<n-2+n-2+1)lim=lim<<1;
  77. rep(1,lim-1,i)rev[i]=rev[i>>1]>>1|((i&1)?lim>>1:0);
  78. INV=ksm(lim,mod-2);
  79. rep(1,n,i)
  80. {
  81. int ww=1;
  82. rep(0,n-2,j)
  83. {
  84. ww=(ll)ww*w[i]%mod;
  85. f[j]=(ll)f[j]*fac[n-2-j]%mod;
  86. g[j]=(ll)inv[j]*(j+1)%mod*ww%mod;
  87. }
  88. rep(n-1,lim-1,j)f[j]=0,g[j]=0;
  89. NTT(g,1);NTT(f,1);rep(0,lim-1,j)f[j]=(ll)f[j]*g[j]%mod;
  90. NTT(f,-1);rep(0,n-2,j)f[j]=(ll)f[j]*INV%mod*inv[n-2-j]%mod;
  91. }
  92. put(f[n-2]);
  93. return 0;
  94. }
  95. score 100
  96. const int MAXN=300010,GG=3;
  97. int n;
  98. int w[MAXN],O[MAXN],rev[MAXN],f[MAXN],g[MAXN];
  99. int fac[MAXN],inv[MAXN],C[MAXN],D[MAXN],ans[MAXN];
  100. int A[20][MAXN],tv[MAXN],v[MAXN],E[MAXN],F[MAXN],G[MAXN];
  101. inline int ksm(int b,int p)
  102. {
  103. int cnt=1;
  104. while(p)
  105. {
  106. if(p&1)cnt=(ll)cnt*b%mod;
  107. b=(ll)b*b%mod;p=p>>1;
  108. }
  109. return cnt;
  110. }
  111. inline void NTT(int *a,int op,int lim)
  112. {
  113. rep(1,lim-1,i)
  114. {
  115. rev[i]=rev[i>>1]>>1|((i&1)?lim>>1:0);
  116. if(i<rev[i])swap(a[i],a[rev[i]]);
  117. }
  118. for(int len=2;len<=lim;len=len<<1)
  119. {
  120. int mid=len>>1;
  121. int wn=ksm(GG,op==1?(mod-1)/len:mod-1-(mod-1)/len);
  122. rep(1,mid-1,i)O[i]=(ll)O[i-1]*wn%mod;
  123. for(int j=0;j<lim;j+=len)
  124. {
  125. for(int i=0;i<mid;++i)
  126. {
  127. int x=a[i+j],y=(ll)a[i+j+mid]*O[i]%mod;
  128. a[i+j]=(x+y)%mod;a[i+j+mid]=(x-y+mod)%mod;
  129. }
  130. }
  131. }
  132. if(op==-1)for(int i=0,INV=ksm(lim,mod-2);i<=lim-1;++i)a[i]=(ll)a[i]*INV%mod;
  133. }
  134. inline void solve(int l,int r,int d)
  135. {
  136. if(l==r)return A[d][0]=1,A[d][1]=mod-w[l],void();
  137. int mid=(l+r)>>1;
  138. solve(l,mid,d);solve(mid+1,r,d+1);
  139. int lim=1;while(lim<=r-l+1)lim=lim<<1;
  140. rep(mid-l+2,lim-1,i)A[d][i]=0;
  141. rep(r-mid+1,lim-1,i)A[d+1][i]=0;
  142. NTT(A[d],1,lim);NTT(A[d+1],1,lim);
  143. rep(0,lim-1,i)A[d][i]=(ll)A[d][i]*A[d+1][i]%mod;
  144. NTT(A[d],-1,lim);
  145. }
  146. inline void Direv(int *A,int *B,int len)
  147. {
  148. rep(1,len-1,i)B[i-1]=(ll)A[i]*i%mod;B[len-1]=0;
  149. }
  150. inline void Inv(int *A,int *B,int len)
  151. {
  152. if(len==1)return B[0]=ksm(A[0],mod-2),void();
  153. Inv(A,B,len>>1);rep(0,len-1,i)E[i]=A[i],F[i]=B[i];
  154. NTT(E,1,len<<1);NTT(F,1,len<<1);
  155. rep(0,(len<<1)-1,i)E[i]=(ll)E[i]*F[i]%mod*F[i]%mod;
  156. NTT(E,-1,len<<1);
  157. rep(0,len-1,i)B[i]=((ll)2*B[i]-E[i]+mod)%mod;
  158. rep(0,(len<<1)-1,i)E[i]=F[i]=0;
  159. }
  160. inline void Inter(int *A,int *B,int len)
  161. {
  162. rep(1,len-1,i)B[i]=(ll)A[i-1]*inv[i]%mod*fac[i-1]%mod;B[0]=0;
  163. }
  164. inline void Ln(int *A,int *B,int len)
  165. {
  166. Direv(A,C,len);Inv(A,D,len);
  167. NTT(C,1,len<<1);NTT(D,1,len<<1);
  168. rep(0,(len<<1)-1,i)C[i]=(ll)C[i]*D[i]%mod;
  169. NTT(C,-1,len<<1);Inter(C,B,len);
  170. rep(0,(len<<1)-1,i)C[i]=D[i]=0;
  171. }
  172. inline void Exp(int *A,int *B,int len)
  173. {
  174. if(len==1)return B[0]=1,void();
  175. Exp(A,B,len>>1);Ln(B,G,len);
  176. G[0]=(A[0]+1-G[0]+mod)%mod;
  177. rep(1,len-1,i)G[i]=(A[i]-G[i]+mod)%mod;
  178. NTT(B,1,len<<1);NTT(G,1,len<<1);
  179. rep(0,(len<<1)-1,i)B[i]=(ll)B[i]*G[i]%mod;
  180. NTT(B,-1,len<<1);
  181. rep(len,(len<<1)-1,i)B[i]=G[i]=0;
  182. }
  183. int main()
  184. {
  185. freopen("yuyuko.in","r",stdin);
  186. freopen("yuyuko.out","w",stdout);
  187. get(n);
  188. if(n==1){puts("0");return 0;}
  189. rep(1,n,i)get(w[i]);
  190. //先求出G(x)=1+ai^kx^k;
  191. int len=1;fac[0]=1;O[0]=1;
  192. while(len<=n)len=len<<1;
  193. rep(1,(len<<1),i)fac[i]=(ll)fac[i-1]*i%mod;
  194. inv[len<<1]=ksm(fac[len<<1],mod-2);
  195. fep((len<<1)-1,0,i)inv[i]=(ll)inv[i+1]*(i+1)%mod;
  196. solve(1,n,0);rep(0,n,i)tv[i]=A[0][i];
  197. Ln(tv,v,len);v[0]=n;
  198. rep(1,len-1,i)v[i]=mod-(ll)v[i]*i%mod;
  199. rep(0,len-1,i)f[i]=(ll)inv[i]*(i+1)%mod;
  200. Ln(f,g,len);
  201. rep(0,len-1,i)g[i]=(ll)g[i]*v[i]%mod;
  202. Exp(g,ans,len);
  203. int res=(ll)ans[n-2]*fac[n-2]%mod;
  204. rep(1,n,i)res=(ll)res*w[i]%mod;
  205. put(res);return 0;
  206. }

5.13 省选模拟赛 优雅的绽放吧,墨染樱花 多项式 prufer序列 计数 dp的更多相关文章

  1. 4.13 省选模拟赛 树 树形dp 卷积 NTT优化dp.

    考试的时候 看到概率 看到期望我就怂 推了一波矩阵树推自闭了 发现 边权点权的什么也不是. 想到了树形dp 维护所有边的断开情况 然后发现数联通块的和再k次方过于困难. 这个时候 应该仔细观察一下 和 ...

  2. 4.13 省选模拟赛 传销组织 bitset 强连通分量 分块

    考试的时候昏了头 没算空间 这道题我爆零了.值得注意的是 一般认为bitset的空间是 int 的1/w倍 对于那m条边 无论如何构造 这m条关系都是存在的 题目其实是想让我们用这m条关系来计算给出的 ...

  3. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  4. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  5. 3.28 省选模拟赛 染色 LCT+线段树

    发现和SDOI2017树点涂色差不多 但是当时这道题模拟赛的时候不会写 赛后也没及时订正 所以这场模拟赛的这道题虽然秒想到了LCT和线段树但是最终还是只是打了暴力. 痛定思痛 还是要把这道题给补了. ...

  6. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

  7. NOI 2019 省选模拟赛 T1【JZOJ6082】 染色问题(color) (多项式,数论优化)

    题面 一根长为 n 的无色纸条,每个位置依次编号为 1,2,3,-,n ,m 次操作,第 i 次操作把纸条的一段区间 [l,r] (l <= r , l,r ∈ {1,2,3,-,n})涂成颜色 ...

  8. 【FJOI 20170305】省选模拟赛

    题面被改成了个猪... T1猪猪划船(boat) [题目描述] 6只可爱的猪猪们一起旅游,其中有3只大猪A,B,C,他们的孩子为3只小猪a,b,c.由于猪猪们十分凶残,如果小猪在没有父母监护的情况下, ...

  9. NOI2019省选模拟赛 第五场

    爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...

随机推荐

  1. HTML的<Object>标签怎么用?

    <object>标签是一个HTML标签,用于在网页中显示音频,视频,图像,PDF和Flash等多媒体:它通常用于嵌入由浏览器插件处理的Flash页面元素,如Flash和Java项目.它还可 ...

  2. MySQL实验 子查询优化双参数limit

    MySQL实验 子查询优化双参数limit 没想到双参数limit还有优化的余地,为了亲眼见到,今天来亲自实验一下.   实验准备 使用MySQL官方的大数据库employees进行实验,导入该示例库 ...

  3. MVC + EFCore 项目实战 - 数仓管理系统2- 搭建基本框架配置EFCore

    本次课程就正式进入开发部分. 首先我们先搭建项目框架,还是和之前渐进式风格保持一致,除必备组件外,尽量使用原生功能以方便大家理解. 开发工具:vs 2019 或以上 数据库:SQL SERVER 20 ...

  4. django中的懒加载机制

    懒加载在前端中的意义: 懒加载的主要目的就是作为服务器前端的优化,减少请求次数或者延迟请求数. 实现原理: 先加载一部分数据,当触发某个条件时利用异步加载剩余的数据,新得到的数据不会影响原有数据的显示 ...

  5. JQ滚动加载

    $(window).scroll(function () { if ($(document).scrollTop() + $(window).height() >= $(document).he ...

  6. html2canvas截图问题,图片跨域导致截图空白

    年前的一个项目,要做一个H5截屏分享的功能,使用的是html2canvas插件,截图功能是实现了,但是跨域的图片死活不出来, 经过几天谷歌百度和不断的尝试,终于找到解决办法了,一共经历了让人心力憔悴的 ...

  7. Python OpenCV的绘图功能简介

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:大Z 在图像中我们经常需要用到将某个局部特征画出来,比如物体检测,物 ...

  8. 最新Spark入门篇

    一.Spark简介 1.什么是Spark Apache Spark是一种快速的集群计算技术,基于Hadoop MapReduce技术,扩展了MapReduce模型,主要特性是在内存中集群计算,速度更快 ...

  9. 关于flask(前后端分离)的后端开发的小白笔记整理(含postman,jwt,json,SQLAlchemy等)

    首先是提醒自己的一些唠嗑: 学会劳逸结合,文档看累了可以看视频,动手操作很关键,遇到问题先动脑子冷静地想,不要跟着步骤都不带脑子,想不出来了再查一查!有时候打出来的代码很虚,但是实践不花钱,实践出真知 ...

  10. POJ 1095 Trees Made to Order 最详细的解题报告

    题目来源:Trees Made to Order 题目大意:根据下面的规则给一棵二叉树编号: 规则1:如果二叉树为空,则编号为0: 规则2:如果二叉树只有一个节点,则编号为1: 规则3:所有含有m个节 ...