题目

一颗\(n\)个节点的树,每个点有一个权值\(a_i\)

询问树上连通块权值之和对 \(m\) 取模为$ x $ 的方案数

答案对\(950009857\) 取模,满足\(m | 950009856\)

空间\(32 \ M\)

题解

  • 考虑\(F_i(x)\)为i为根的连通块的生成函数,\(G(x)\)为答案的生成函数

    \[\begin{align}
    F_i(x) \ = \ (\prod F_{son(i)}+1)x^{a_i} \\
    G(x) \ = \ \sum F_i(x) \\
    \end{align}
    \]

  • 一个比较naive的想法就是每次都dft,idft之后手动将系数取模,但其实没有必要

  • 可以直接对每个点求出dft,O(nm)求出点乘后的结果,最后做一次idft之后的到的答案就是循环卷积

    注意每个点的形式是\(x^a_i\),预处理单位根的次幂可以直接得到dft

  • 对于空间,重链剖分之后把一个点的数组直接传给重儿子,一个点dfs完之后回收一下

    最大引用数组就是一条链上的轻链个数

  • 时间复杂度:\(O(nm + m \ log \ m)\) ; 空间复杂度:\(O(m \ log \ n)\)

  • 为什么idft之后的结果是循环卷积呢?

    \[\begin{align}
    &考虑一个次数界为n的式子\{A_i\}在m次下的点值表达:\{dft(A)_i\}\\
    &设\{B_i\}为idft之后的结果\\
    &B_r = \sum_{j=0}^{m-1}\frac{1}{m}dft(A)_j \omega_m^{-jr}\\
    &= \sum_{j=0}^{m-1}\sum_{k=0}^{n-1}\frac{1}{m}A_k \omega_m^{j(k-r)}\\
    &= \sum_{k=0}^{n-1}A_k (\sum_{j=0}^{m-1}\frac{1}{m}\omega_m^{j(k-r)})\\
    &运用求和引理,B_r = \sum_{j=0}^{n-1}A_k[m|j-r]\\
    &即m次意义下的循环卷积
    \end{align}
    \]

Code

  1. #include<bits/stdc++.h>
  2. #define mod 950009857
  3. using namespace std;
  4. const int N=1<<18,M=14,R=7;
  5. int n,m,a[N],o=1,hd[N],sz[N],sn[N],f[M][N],q[M],head,tail,now,id[N],g[N];
  6. int t1[N],t2[N],len,L,rev[N],w[N],W[N];
  7. struct Edge{int v,nt;}E[N<<1];
  8. void adde(int u,int v){
  9. E[o]=(Edge){v,hd[u]};hd[u]=o++;
  10. E[o]=(Edge){u,hd[v]};hd[v]=o++;
  11. }
  12. void inc(int&x,int y){x+=y;if(x>=mod)x-=mod;}
  13. void dfsA(int u,int fa){
  14. sz[u]=1;
  15. for(int i=hd[u];i;i=E[i].nt){
  16. int v=E[i].v;
  17. if(v==fa)continue;
  18. dfsA(v,u);
  19. sz[u]+=sz[v];
  20. if(sz[v]>sz[sn[u]])sn[u]=v;
  21. }
  22. }
  23. int get(){
  24. if(head==tail)q[tail++]=++now;
  25. if(tail==21)tail=0;
  26. int re=q[head++],*F=f[re];
  27. for(int i=0;i<m;++i)F[i]=1;
  28. if(head==21)head=0;
  29. return re;
  30. }
  31. void pop(int x){
  32. q[tail++]=x;
  33. if(tail==21)tail=0;
  34. }
  35. void dfsB(int u,int fa){
  36. if(sn[u]){
  37. dfsB(sn[u],u);
  38. id[u]=id[sn[u]];
  39. int *F=f[id[u]];
  40. for(int i=0;i<m;++i)inc(F[i],1);
  41. }else id[u]=get();
  42. int *F=f[id[u]];
  43. for(int i=0,t=0;i<m;++i){
  44. F[i]=1ll*F[i]*w[t]%mod;
  45. t+=a[u];if(t>=m)t-=m;
  46. }
  47. for(int i=hd[u];i;i=E[i].nt){
  48. int v=E[i].v;
  49. if(v==fa||v==sn[u])continue;
  50. dfsB(v,u);
  51. int *G=f[id[v]];
  52. for(int j=0;j<m;++j)F[j]=1ll*F[j]*(G[j]+1)%mod;
  53. pop(id[v]);
  54. }
  55. for(int i=0;i<m;++i)inc(g[i],F[i]);
  56. }
  57. int pw(int x,int y){
  58. int re=1;if(y<0)y+=mod-1;
  59. for(;y;y>>=1,x=1ll*x*x%mod)
  60. if(y&1)re=1ll*re*x%mod;
  61. return re;
  62. }
  63. void ntt(int*A,int F){
  64. for(int i=0;i<len;++i)if(i<rev[i])swap(A[i],A[rev[i]]);
  65. for(int i=1;i<len;i<<=1){
  66. int wn=pw(R,F*(mod-1)/i/2);
  67. for(int j=0;j<len;j+=i<<1){
  68. int t=1;
  69. for(int k=0;k<i;++k,t=1ll*t*wn%mod){
  70. int x=A[j+k],y=1ll*t*A[j+k+i]%mod;
  71. A[j+k]=(x+y)%mod;A[j+k+i]=(x-y+mod)%mod;
  72. }
  73. }
  74. }
  75. if(!~F){
  76. int iv=pw(len,mod-2);
  77. for(int i=0;i<len;++i)A[i]=1ll*A[i]*iv%mod;
  78. }
  79. }
  80. int main(){
  81. freopen("tree.in","r",stdin);
  82. freopen("tree.out","w",stdout);
  83. scanf("%d%d",&n,&m);
  84. w[0]=1;w[1]=pw(R,(mod-1)/m);
  85. for(int i=2;i<=m;++i)w[i]=1ll*w[i-1]*w[1]%mod;
  86. for(int i=1;i<=n;++i)scanf("%d",&a[i]);
  87. for(int i=1;i<n;++i){
  88. int u,v;
  89. scanf("%d%d",&u,&v);
  90. adde(u,v);
  91. }
  92. dfsA(1,0);
  93. dfsB(1,0);
  94. for(len=1,L=0;len<=(m-1)*3;len<<=1,++L);
  95. for(int i=1;i<len;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
  96. for(int i=0;i<=(m-1)<<1;++i){
  97. W[i]=w[1ll*i*(i-1)/2%m];
  98. t2[i]=pw(W[i],mod-2);
  99. }
  100. for(int i=0;i<m;++i)t1[i]=1ll*g[m-1-i]*W[m-1-i]%mod;
  101. ntt(t1,1);ntt(t2,1);
  102. for(int i=0;i<len;++i)t1[i]=1ll*t1[i]*t2[i]%mod;
  103. ntt(t1,-1);
  104. int iv=pw(m,mod-2);
  105. for(int i=0;i<m;++i)printf("%d ",1ll*iv*W[i]%mod*t1[m-1+i]%mod);
  106. return 0;
  107. }

【JZOJ6239】【20190629】智慧树的更多相关文章

  1. CSDN不限积分代下载,知网、万方、sci、IEEE论文代下载,智慧树、超星尔雅刷课

    下载内容: 1.CSDN不限积分代下载. 2.知网.万方.sci.IEEE论文代下载. 3.超星尔雅,智慧树刷课. 注:由于本人手抖买一个CSDN会员,想挽回一点损失,所以创立了一个下载群,绝对不是骗 ...

  2. 用Python来自动刷智慧树网站的网课

    学校最近让看什么网课,智慧树网站的,太无聊了,写个脚本刷下,这里是用Python+selenium实现的,也可以用js脚本,更简单,但是我这里刚好最近在学python,就顺便练习下,说下有几个点, 1 ...

  3. 智慧树刷网课python脚本

    0x00 写在前面 疫情期间肯定有很多小伙伴需要上网课,但是有些网课我们感觉十分的鸡肋,自己不感兴趣,又必须要学 所以我写了这个刷网课的小程序,一方面是锻炼自己的爬虫技术,另一方面也给同学们节约宝贵的 ...

  4. 智慧树mooc自动刷课代码

    最近学习javaScript和JQuery,恰好还有一门mooc没有看.结合学习的知识和其他人的代码:撸了一个自动播放课程的代码,同时自动跳过单章的测试题. 用电脑挂着不动就完事了. 如下: var ...

  5. 分布式任务调度平台XXL-JOB

    <分布式任务调度平台XXL-JOB>       一.简介 1.1 概述 XXL-JOB是一个轻量级分布式任务调度框架,其核心设计目标是开发迅速.学习简单.轻量级.易扩展.现已开放源代码并 ...

  6. Bluestein's Algorithm

    网上很少有人提到,写的也很简单,事实上就是很简单... \(Bluestein's\ Algorithm\),用以解决任意长度\(DFT\). 考虑\(DFT\)的形式:\[\begin{aligne ...

  7. php编写刷网课自助下单系统(第三方支付实例)

    此项目是由于本人刚刚入门php且在校代刷网课而编写的,由于在上课时间不方便接单,故特意写一个自助下单系统来实现客户自助下单.本项目主要实现以下功能:1.用户下单2.用户支付3.用户通过账号查询订单4. ...

  8. Comet OJ 夏季欢乐赛 完全k叉树

    完全k叉树 https://cometoj.com/contest/59/problem/A?problem_id=2712 题目描述 欢迎报考JWJU!这里有丰富的社团活动,比如为梦想奋斗的ACM集 ...

  9. 【重庆师范大学】PHP博客训练-Thinkphp

    设计数据库 CREATE TABLE `user` ( `user_id` int unsigned NOT NULL AUTO_INCREMENT, `username` varchar() COM ...

随机推荐

  1. Linux 分区管理器

    下面的列表没有特定的排名顺序.大多数分区工具应该存在于 Linux 发行版的仓库中. GParted 这可能是 Linux 发行版中最流行的基于 GUI 的分区管理器.你可能已在某些发行版中预装它.如 ...

  2. 2019-11-29-WPF-依赖属性绑定不上调试方法

    原文:2019-11-29-WPF-依赖属性绑定不上调试方法 title author date CreateTime categories WPF 依赖属性绑定不上调试方法 lindexi 2019 ...

  3. Lisp : (quote) code is data (eval) data as code

  4. ASP.NET MVC自定义Module记录管道事件执行顺序

    1. 在Visual Studio 新建项目,模板为空,下面结构选择MVC. 2. 在项目中新建一个类MyModule,实现IHttpModule接口 namespace SimpleApp.Infr ...

  5. np.broadcast_to()的函数使用及维度增加的表达

    import numpy as npanchors=np.ones((2,3))anchor = np.broadcast_to(anchors, (5,)+anchors.shape) # 标红字体 ...

  6. HighChat 动态绑定数据记录

    最近刚开始做图形操作,纠结了一上午,highchat 动态绑定数据这块一直不知道怎么绑定,后来多次尝试,发现 1.x轴的数据是个数组格式,我从后台传到前台的时候,js中用数组进行处理数据,然后赋值到c ...

  7. 开发工具--浅谈Git

    工具|浅谈Git Git这个工具,是我一直想写文章,终于我实现了我的想法.在我开始写之前,发表一下自己的看法,git只是一个工具,既然已经认定是一个工具,那么一定具备工具这类的共同特征,请用面向对象的 ...

  8. 写 React / Vue 项目时为什么要在列表组件中写 key,其作用是什么

    怼一波,在项目中有很多经常用到,但又含糊不清的知识点 框架中的key: 1. 为啥在遍历元素时要用 key :在开发过程中为了保证遍历同级元素的唯一性,用来提高更新 dom 的性能: 2. 凭啥要保证 ...

  9. i春秋——“百度杯”CTF比赛 十月场——EXEC(命令执行、带外通道传输数据)

    查看源码得知由vim编写,所以查找备份以及交换文件 找到 /.index.php.swp ,下载后用vim -r恢复该文件即可得到源码 1 <html> 2 <head> 3 ...

  10. Solr缓存原理分析及配置优化

    一.缓存原理 缓存,带来急速性能体验! Solr提供了一系列的内置缓存来优化查询性能.Solr的缓存原理主要涉及以下4个方面: 1.缓存大小及缓存置换法 从缓存大小的角度来看,不能将缓存设置的太大,否 ...