首先注意到n个点的仙人掌其实和n个圆点的圆方树是等价的,那么转化为求圆方树的统计会简单一点。
圆方树要满足的性质有以下几条:

1.奇数层为圆点,偶数层为方点,即只存在圆点和方点连的边。

2.圆点下的子树是不计顺序的(即仙人掌中一个点连出去几个环没关系)。

3.方点下的子树和顺序有关系,但正反相同的顺序视为一样(即仙人掌中环上的点顺序是有影响的,并且正反顺序是相同的)。

一般来讲,正反顺序视为相同的套路都是把回文的加上再除以2.

记 f n f_n fn​为以圆点为根的有 n n n个圆点的圆方树个数, g n g_n gn​为以方点为根的有 n n n个圆点的圆方树个数。

再设 g 1 n g1_n g1n​为有 n n n个圆点的以圆点为根的圆方树森林, g 2 n g2_n g2n​为有 n n n个圆点的奇数棵圆方树森林, g 3 n g3_n g3n​为有 n n n个圆点的偶数棵圆方树森林,则直接考虑暴力的话有:

g 1 n = ∑ i = 1 n g 1 n − i ⋅ f i g1_n=\sum_{i=1}^ng1_{n-i}\cdot f_i g1n​=∑i=1n​g1n−i​⋅fi​

g 2 n = ∑ i = 1 n g 3 n − i ⋅ f i g2_n=\sum_{i=1}^ng3_{n-i}\cdot f_i g2n​=∑i=1n​g3n−i​⋅fi​

g 3 n = [ 2 ∣ n ] g 1 n 2 g3_n=[2|n]g1_{\frac{n}2} g3n​=[2∣n]g12n​​

g n = g 1 n + g 2 n + g 3 n 2 g_n=\frac{g1_n+g2_n+g3_n}2 gn​=2g1n​+g2n​+g3n​​

而 f n f_n fn​则等价于在 g [ 1... n − 1 ] g[1...n-1] g[1...n−1]中选出总点数为n-1的方点子树,即做一遍完全背包。


直接暴力复杂度肯定是不对的, g 1 , g 2 , g 3 , g g1,g2,g3,g g1,g2,g3,g的计算容易用 N T T NTT NTT加速,下面考虑如何快速计算 f n f_n fn​.

(以下部分涉及到2015年集训队论文)

记 f ( x ) = ∑ i = 1 ∞ f n x n − 1 f(x)=\sum_{i=1}^\infty f_nx^{n-1} f(x)=∑i=1∞​fn​xn−1,并对每种 g i g_i gi​写出生成函数,相乘后有 f ( x ) = ∏ i ( 1 + x + x 2 + ⋯   ) g i = ∏ i ( 1 1 − x i ) g i f(x)=\prod_i(1+x+x^2+\cdots)^{g_i}=\prod_i(\frac1{1-x^i})^{g_i} f(x)=∏i​(1+x+x2+⋯)gi​=∏i​(1−xi1​)gi​.

两边取对数: ln ⁡ f ( x ) = − ∑ i g i ⋅ l n ( 1 − x i ) = ∑ i g i ⋅ ∑ j = 1 ∞ x i j j \ln f(x)=-\sum_i g_i\cdot ln(1-x^i)=\sum_ig_i\cdot\sum_{j=1}^\infty\frac{x^{ij}}j lnf(x)=−∑i​gi​⋅ln(1−xi)=∑i​gi​⋅∑j=1∞​jxij​.

两边取导数: d d x ln ⁡ f ( x ) = f ′ ( x ) f ( x ) = ∑ i = 1 ∞ ( n − 1 ) f n x n − 2 ∑ i = 1 ∞ f n x n − 1 \frac d{dx} \ln f(x)=\frac{f'(x)}{f(x)}=\frac{\sum_{i=1}^\infty(n-1)f_nx^{n-2}}{\sum_{i=1}^\infty f_nx^{n-1}} dxd​lnf(x)=f(x)f′(x)​=∑i=1∞​fn​xn−1∑i=1∞​(n−1)fn​xn−2​.

​ d d x ( ∑ i g i ⋅ ∑ j = 1 ∞ x i j j ) = ∑ i g i ⋅ ∑ j = 1 ∞ i ⋅ x i j − 1 = ∑ i i g i ⋅ ∑ j = 1 ∞ x i j − 1 \frac d{dx}(\sum_ig_i\cdot\sum_{j=1}^\infty\frac{x^{ij}}j)=\sum_ig_i\cdot\sum_{j=1}^\infty i\cdot x^{ij-1}=\sum_iig_i\cdot\sum_{j=1}^\infty x^{ij-1} dxd​(∑i​gi​⋅∑j=1∞​jxij​)=∑i​gi​⋅∑j=1∞​i⋅xij−1=∑i​igi​⋅∑j=1∞​xij−1

​ 即: ∑ i = 1 ∞ ( n − 1 ) f n x n − 2 ∑ i = 1 ∞ f n x n − 1 = ∑ i i g i ⋅ ∑ j = 1 ∞ x i j − 1 \frac{\sum_{i=1}^\infty(n-1)f_nx^{n-2}}{\sum_{i=1}^\infty f_nx^{n-1}}=\sum_iig_i\cdot\sum_{j=1}^\infty x^{ij-1} ∑i=1∞​fn​xn−1∑i=1∞​(n−1)fn​xn−2​=∑i​igi​⋅∑j=1∞​xij−1 .

​ 即: ∑ i = 1 ∞ ( n − 1 ) f n x n − 2 = ( ∑ i = 1 ∞ f n x n − 1 ) ⋅ ( ∑ i i g i ⋅ ∑ j = 1 ∞ x i j − 1 ) \sum_{i=1}^\infty(n-1)f_nx^{n-2}=(\sum_{i=1}^\infty f_nx^{n-1})\cdot(\sum_iig_i\cdot\sum_{j=1}^\infty x^{ij-1}) ∑i=1∞​(n−1)fn​xn−2=(∑i=1∞​fn​xn−1)⋅(∑i​igi​⋅∑j=1∞​xij−1).

为了形式好看,两边再乘以 x 2 x^2 x2: ∑ i = 1 ∞ ( n − 1 ) f n x n = ( ∑ i = 1 ∞ f n x n ) ⋅ ( ∑ i i g i ⋅ ∑ j = 1 ∞ x i j ) \sum_{i=1}^\infty(n-1)f_nx^n=(\sum_{i=1}^\infty f_nx^n)\cdot(\sum_iig_i\cdot\sum_{j=1}^\infty x^{ij}) ∑i=1∞​(n−1)fn​xn=(∑i=1∞​fn​xn)⋅(∑i​igi​⋅∑j=1∞​xij)

继续化简等式右边地第二个括号,令 t = i j t=ij t=ij并交换求和顺序: ∑ i i g i ⋅ ∑ j = 1 ∞ x i j = ∑ t = 1 ∞ x t ⋅ ∑ i ∣ t i g i \sum_iig_i\cdot\sum_{j=1}^\infty x^{ij}=\sum_{t=1}^\infty x^t\cdot\sum_{i|t}ig_i ∑i​igi​⋅∑j=1∞​xij=∑t=1∞​xt⋅∑i∣t​igi​

即: ∑ i = 1 ∞ ( n − 1 ) f n x n = ( ∑ i = 1 ∞ f n x n ) ⋅ ( ∑ t = 1 ∞ x t ⋅ ∑ i ∣ t i g i ) \sum_{i=1}^\infty(n-1)f_nx^n=(\sum_{i=1}^\infty f_nx^n)\cdot(\sum_{t=1}^\infty x^t\cdot\sum_{i|t}ig_i) ∑i=1∞​(n−1)fn​xn=(∑i=1∞​fn​xn)⋅(∑t=1∞​xt⋅∑i∣t​igi​)

特别地,两边对应项系数相等: ( n − 1 ) f n = ∑ i ( ∑ j ∣ i j g j ) f n − i (n-1)f_n=\sum_i(\sum_{j|i}jg_j)f_{n-i} (n−1)fn​=∑i​(∑j∣i​jgj​)fn−i​,即 f n = 1 n − 1 ∑ i ( ∑ j ∣ i j g j ) f n − i f_n=\frac1{n-1}\sum_i(\sum_{j|i}jg_j)f_{n-i} fn​=n−11​∑i​(∑j∣i​jgj​)fn−i​.

若令 f t n = ∑ j ∣ i j g j ft_n=\sum_{j|i}jg_j ftn​=∑j∣i​jgj​,则 f n = 1 n − 1 ∑ i f t i f n − i f_n=\frac1{n-1}\sum_ift_if_{n-i} fn​=n−11​∑i​fti​fn−i​.

注意到这也是一个卷积的形式,结合上面的 g 1 , g 2 , g 3 , g g1,g2,g3,g g1,g2,g3,g,直接上分治 F F T FFT FFT即可。

注意特判 f 1 = 1 f_1=1 f1​=1。

#include<bits/stdc++.h>
#define maxn 500050
#define inv2 499122177
#define modu 998244353
using namespace std;
typedef long long LL;LL pw(LL a,LL k=modu-2)   {LL ans=1;for (;k;k>>=1)  {if (k&1)ans=ans*a%modu;a=a*a%modu;}return ans;
}struct NTT  {LL I,w[maxn];int N,rev[maxn];void init(int n)    {for (N=1;N<n;N<<=1);   I=pw(N);rev[0]=0,rev[1]=N>>1;for (int i=2;i<N;++i)rev[i]=rev[i>>1]>>1|rev[i&1];w[0]=1,w[1]=pw(3,(modu-1)/N);for (int i=2;i<N;++i)w[i]=w[i-1]*w[1]%modu;}void DFT(LL *A) {for (int i=0;i<N;++i)if (i<rev[i])swap(A[i],A[rev[i]]);for (int len=2;len<=N;len<<=1)  {int m=len>>1;for (LL *p=A;p!=A+N;p+=len)for (int i=0;i<m;++i)   {LL u=p[i],v=p[i+m]*w[N/len*i]%modu;p[i]=(u+v)%modu;p[i+m]=(u-v+modu)%modu;}}}void IDFT(LL *A)    {DFT(A);reverse(A+1,A+N);for (int i=0;i<N;++i)A[i]=A[i]*I%modu;}
} T;int n;LL I[maxn]={1,1};// inverse of iLL f[maxn];//n node cactus i.e. n circle node yuan fang tree.
LL g[maxn];//n node cactus sequence (no symmetry)
LL ft[maxn];//\sum_{j|i} j*g_j
LL g1[maxn];//n node cactus squence (can be symmetric)
LL g2[maxn];//n node cactus symmetric squence with odd length
LL g3[maxn];//n node cactus symmetric squence with even lengthLL ta[maxn],tb[maxn],tc[maxn];void add(LL &a,LL b)    {a=(a+b)%modu;
}void clear(LL *A)   {for (int i=0;i<T.N;++i) A[i]=0;
}void contri(int l1,int r1,int l2,int r2,int l3,int r3)    {clear(ta),clear(tb);for (int i=l1;i<=r1;++i)    ta[i-l1]=f[i];T.DFT(ta);auto calc=[&](LL *c,LL *b)  {clear(tb);for (int i=l2;i<=r2;++i)    tb[i-l2]=b[i];T.DFT(tb);for (int i=0;i<T.N;++i) tc[i]=ta[i]*tb[i]%modu;T.IDFT(tc);for (int i=0;i<T.N;++i) {int t=i+l1+l2;if (l3<=t&&t<=r3)add(c[t],tc[i]);}};calc(f,ft);calc(g1,g1);calc(g2,g3);
}void solve(int l,int r)  {if (l==r)   {if (l==1)f[l]=1;elsef[l]=f[l]*I[l-1]%modu;add(g1[l],f[l]);add(g2[l],f[l]);if (~l&1)   g3[l]=g1[l>>1];g[l]=(g1[l]+g2[l]+g3[l])*inv2%modu;for (int j=l;j<=n;j+=l)add(ft[j],l*g[l]);return ;}int mid=(l+r)>>1;solve(l,mid);T.init(r-l<<1);auto calc=[&](int l1,int r1,int l2,int r2) {contri(l1,r1,l2,r2,mid+1,r);};if (l>1) calc(l,mid,1,r-l),calc(1,r-l,l,mid);calc(l,mid,l,mid);solve(mid+1,r);
}void brute()    {for (int i=1;i<=n;++i)  {if (i==1)   f[1]=1;else    {for (int j=1;j<i;++j)   add(f[i],f[i-j]*ft[j]);for (int j=1;j<i;++j)   add(g1[i],f[i-j]*g1[j]);for (int j=1;j<i;++j)   add(g2[i],f[i-j]*g3[j]);f[i]=f[i]*I[i-1]%modu;}add(g1[i],f[i]);add(g2[i],f[i]);if (~i&1)  g3[i]=g1[i>>1];g[i]=(g1[i]+g2[i]+g3[i])*inv2%modu;for (int j=i;j<=n;j+=i) add(ft[j],i*g[i]);}
}int main()  {scanf("%d",&n);for (int i=2;i<=n;++i)  I[i]=modu-modu/i*I[modu%i]%modu;solve(1,n);// brute();for (int i=1;i<=n;++i)printf("%lld\n",f[i]);return 0;
}

2019hdu多校第一场H Desert [多项式计数] [仙人掌计数]相关推荐

  1. 2019HDU多校第一场1001 BLANK (DP)(HDU6578)

    2019HDU多校第一场1001 BLANK (DP) 题意:构造一个长度为n(n<=10)的序列,其中的值域为{0,1,2,3}存在m个限制条件,表示为 l r x意义为[L,R]区间里最多能 ...

  2. FFT ---- 2021牛客多校第一场 H Hash Function

    题目链接 题目大意: 解题思路: 首先我们知道任意两个数%seed\%seed%seed都不相同→\rightarrow→(aj−ai)%seed≠0(∀ai≤aj)(a_j-a_i)\%seed\n ...

  3. [2019HDU多校第一场][HDU 6578][A. Blank]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6578 题目大意:长度为\(n\)的数组要求分别填入\(\{0,1,2,3\}\)四个数中的任意一个,有 ...

  4. [2019HDU多校第一场][HDU 6590][M. Code]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6590 题目大意(来自队友):二维平面上有\(n\)个点,每个点要么是黑色要么是白色,问能否找到一条直线 ...

  5. 2019HDU多校第一场 HDU6578 Blank

    http://acm.hdu.edu.cn/showproblem.php?pid=6578 题意:一排有N个空格.空格从左到右依次为1.2.-.N. 汤姆正在用{0,1,2,3}中的一个数字填充每个 ...

  6. 2019牛客多校第一场

    2019牛客多校第一场 题号 题目 知识点 A Monotonic Matrix B Symmetric Matrix C Fluorescent 2 D Two Graphs E Removal F ...

  7. 2020 牛客多校第一场

    2020 牛客多校第一场 A. B-Suffix Array 后缀数组的思想:倍增+桶排序的方式找出一串连续序列后缀的大小.虽说正常使用的时候都是字典序,但是只要修改排序方式,也能够达到一个类似的&q ...

  8. 2019年杭电多校第一场 1001题blank(DP)HDU6578

    2019年杭电多校第一场 1001题blank(DP)HDU6578 解决思路,开一个DP数组来存储0 1 2 3四个字符最后出现的位置,并且在DP中已经==排好序==. DP开四维,DP[i][j] ...

  9. python字符串去重及排序 牛客_2018牛客多校第一场 D.Two Graphs

    题意: n个点,m1条边的图E1,n个点,m2条边的图E2.求图E2有多少子图跟图E1同构. 题解: 用STL的全排列函数next_permutation()枚举映射.对于每一种映射枚举每一条边判断合 ...

最新文章

  1. 联发科首发台积电4nm,新旗舰多核跑分与苹果A15不相上下,网友:MTK也要Yes了?...
  2. php errorcode,php中pdo错误处理方法详解
  3. 链表题目--2 求链表的中间结点 和 求链表中倒数第k个结点
  4. 9-算法 希尔排序 shell_sort
  5. MySQL binlog相关分析
  6. 非期望产出的sbm模型_线性模型 vs. Logistic模型——离散选择模型之二
  7. 如何修复最常见的 macOS 11 Big Sur 问题?
  8. STL容器-queue队列
  9. 二、设置开发、运行环境 (基础教程2)
  10. 为什么要在MD5加密的密码中加“盐”
  11. 时间序列相似性度量-DTW
  12. es java 创建索引_Elasticsearch(ES) 创建索引
  13. Validation failed判断错误
  14. php获取手机本地,PHP通过API获取手机号码归属地
  15. jsp高级DOM和BOM
  16. 操作系统文件管理之FCB
  17. Docker-windows使用教程
  18. 一篇文章读懂什么是大数据
  19. linux查询网卡是百兆还是千兆,查看网卡是百兆还是千兆
  20. 了解你的敌人:跟踪僵尸网络

热门文章

  1. JavaSwing实现简陋计算器和出题器
  2. jsp页面在线显示pdf文件
  3. [HTML/JS]用HTML、JS实现放大图片效果(放大镜)
  4. 网络安全自学笔记08 - Linux之shell
  5. 计算机虚拟化之后如何恢复,cpu虚拟化怎么开启【解决模式】
  6. Eclipse配置server插件
  7. 来谈谈VOIP电话,okcc,人工智能
  8. 基础_ _返回键back
  9. 二分法----一看就会,一写就废
  10. java谓词_Java 8谓词链