[CF438E] 小朋友和二叉树
Description
给定一个整数集合 \(c\),对于每个 \(i\in[1,m]\),求有多少种不同的带点权的二叉树使得这棵树点权和为 \(i\) 并且顶点的点权全部在集合 \(c\) 中。\(m\leq 10^5\)。
Solution
设 \(f[i]\) 为点权为 \(i\) 的二叉树的方案, \(c[i]\) 表示 \(i\) 是否在集合 \(c\) 中。
所以 \(f[i]=\sum\limits_{j=1}^{i} c[j]\cdot\sum\limits_{p=0}^{i-j}f[p]\cdot \sum\limits_{k=0}^{i-j-p}f[k],f[0]=1\)
发现这是个卷积形式,也就是说 \(f[i+j+k]=c[i]\cdot f[j]\cdot f[k]\),即 \(f=c\times f\times f\)。
解一下方程,\(f=\frac{1\pm \sqrt{1-4c}}{2c}\)
然而 \(c\) 的常数项为 \(0\),所以不能求逆。尝试分子有理化解得 \(f=\frac2{1\pm\sqrt{1-4c}}\)
当 \(x=0\) 时,\(c=0,f=1\),所以分母只能取正号。
求逆+开根即可。
Code
#include<bits/stdc++.h>
using std::min;
using std::max;
using std::swap;
using std::vector;
typedef double db;
typedef long long ll;
#define pb(A) push_back(A)
#define pii std::pair<int,int>
#define all(A) A.begin(),A.end()
#define mp(A,B) std::make_pair(A,B)
const int N=4e5+5;
const int mod=998244353;
#define inv(x) ksm(x,mod-2)int lim,rev[N],f[N];
int n,m,tmpa[N],c[N];
int a[N],b[N],tmpb[N];int ksm(int a,int b,int ans=1){while(b){if(b&1) ans=1ll*ans*a%mod;a=1ll*a*a%mod;b>>=1;} return ans;
}void ntt(int *f,int opt){for(int i=0;i<lim;i++) if(i<rev[i]) swap(f[i],f[rev[i]]);for(int mid=1;mid<lim;mid<<=1){int tmp=ksm(3,(mod-1)/(mid<<1));if(opt<0) tmp=inv(tmp);for(int R=mid<<1,j=0;j<lim;j+=R){int w=1;for(int k=0;k<mid;k++,w=1ll*w*tmp%mod){int x=f[j+k],y=1ll*w*f[j+k+mid]%mod;f[j+k]=(x+y)%mod,f[j+k+mid]=(mod+x-y)%mod;}}} if(opt<0)for(int in=inv(lim),i=0;i<lim;i++) f[i]=1ll*f[i]*in%mod;
}void get(int n){lim=1;while(lim<=n) lim<<=1;for(int i=1;i<lim;i++) rev[i]=(rev[i>>1]>>1)|(i&1?lim>>1:0);
}void solveinv(int len,int *a,int *b){if(len==1) return b[0]=inv(a[0]),void();solveinv(len>>1,a,b);get(len);for(int i=0;i<len;i++) tmpa[i]=a[i];ntt(tmpa,1),ntt(b,1);for(int i=0;i<lim;i++) b[i]=1ll*b[i]*(2ll-1ll*tmpa[i]*b[i]%mod+mod)%mod;ntt(b,-1);for(int i=len;i<lim;i++) b[i]=0;for(int i=0;i<lim;i++) tmpa[i]=0;
}void solvesqr(int len,int *a,int *b){if(len==1) return b[0]=1,void();solvesqr(len>>1,a,b);solveinv(len,b,tmpb);get(len);for(int i=0;i<len;i++) tmpa[i]=a[i];ntt(tmpb,1),ntt(tmpa,1);for(int i=0;i<lim;i++) tmpa[i]=1ll*tmpa[i]*tmpb[i]%mod;ntt(tmpa,-1);for(int i=0,inv2=mod+1>>1;i<lim;i++) b[i]=1ll*(tmpa[i]+b[i])%mod*inv2%mod;for(int i=len;i<lim;i++) b[i]=0;for(int i=0;i<lim;i++) tmpa[i]=tmpb[i]=0;
}int getint(){int X=0,w=0;char ch=getchar();while(!isdigit(ch))w|=ch=='-',ch=getchar();while( isdigit(ch))X=X*10+ch-48,ch=getchar();if(w) return -X;return X;
}signed main(){n=getint(),m=getint();for(int i=1;i<=n;i++){int x=getint();a[x]=1;}for(int i=1;i<=m;i++) if(a[i]) a[i]=mod-4;get(m);a[0]=1;solvesqr(lim,a,b);get(m);b[0]++;solveinv(lim,b,c);for(int i=1;i<=m;i++) printf("%lld\n",2ll*c[i]%mod);return 0;
}
转载于:https://www.cnblogs.com/YoungNeal/p/10211170.html
[CF438E] 小朋友和二叉树相关推荐
- [bzoj3625][Codeforces Round #250]小朋友和二叉树 (生成函数)
description 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有n个互异正整数的序列c[1],c[2],-,c[n].如果一棵带点权的有根二叉树满足其所有顶点的权值都在集合{c ...
- BZOJ #3625 CF #438E 小朋友和二叉树
清真多项式题 BZOJ #3625 codeforces #438E 题意 每个点的权值可以在集合$ S$中任取 求点权和恰好为$[1..n]$的不同的二叉树数量 数据范围全是$ 10^5$ $ So ...
- [学习笔记]多项式开根
还是倍增思想 每一层 还要套一个多项式求逆 所以O(nlog^2n),常数也不小 数组比较多 再trick一下 得到: $T=(T'+F*inv(T'))*inv2$ 可以只算一次多项式求逆,一次NT ...
- [bzoj3625][Codeforces 250 E]The Child and Binary Tree(生成函数+多项式运算+FFT)
3625: [Codeforces Round #250]小朋友和二叉树 Time Limit: 40 Sec Memory Limit: 256 MB Submit: 650 Solved: 2 ...
- 【BZOJ3684】大朋友和多叉树(拉格朗日反演)
题目链接 题意 求满足如下条件的多叉树个数: 1.每一个点的儿子个数在给定的集合 \(S\) 内 2.总的叶子节点树为 \(s\) 儿子之间有顺序关系,但节点是没有标号的. Sol 拉格朗日反演板子题 ...
- 有关多项式处理的各种算法总结
有关多项式处理的各种算法总结 有关多项式处理的各种算法总结 前言 1.一些定义的简要介绍 2.牛顿迭代 3.多项式求逆 4.多项式求lnln\ln 5.多项式开方 6.多项式求指数函数(exp) 7. ...
- 几乎刷完了力扣所有的树题,我发现了这些东西
点击蓝色"力扣加加"关注我哟 加个"星标",带你揭开算法的神秘面纱! ❝ 这是力扣加加第「28」篇原创文章 先上下本文的提纲,这个是我用 mindmap 画的一 ...
- GOOD BYE OI
大米饼正式退役了,OI给我带来很多东西 我会的数学知识基本都在下面了 博客园的评论区问题如果我看到了应该是会尽力回答的... 这也是我作为一个OIer最后一次讲课的讲稿 20190731 多项式乘法 ...
- 小朋友学数据结构(3):二叉树的建立和遍历
小朋友学数据结构(3):二叉树的建立和遍历 一.基本概念 BinaryTree.png 二叉树:每个结点的子结点个数不大于2的树,叫做二叉树. 根结点:最顶部的那个结点叫做根结点,根结点是所有子结点的 ...
- CF438E The Child and Binary Tree(有意思的生成函数 + 多项式求逆 + 多项式开方)
整理的算法模板合集: ACM模板 点我看多项式全家桶(●^◡_◡◡^●) CF438E The Child and Binary Tree 简单的黑题 首先我们发现模数为99824435399824 ...
最新文章
- kafka中controller的作用_Kafka 常见问题汇总
- AtCoder AGC037E Reversing and Concatenating
- (转)在Myeclipse中查看android源码就是这么easy
- 7805输入电流有要求吗_防雷!防护电路在PCB走线方面的要求(某500强企业内部资料~)...
- Win-MASM64汇编语言-CMP/CMPSB/CMPSW/CMPSD/JNE/JCXZ
- Hello China操作系统运行截图(完整版)
- 机器学习笔记(1)决策树
- c语言sigaction,C语言中的Sigaction和setitimer
- 2019最新python下载安装详解
- php依赖安装顺序,PHP安装GD依赖
- js 实现2的n次方计算函数_x的10的n次方解决js浮点数计算
- 微信小程序|基于小程序实现人脸识别对比
- 【爬虫1】爬虫和反爬虫介绍
- pycharm 文件名不同颜色所代表的含义
- js实现数组按拼音排序
- 【转】 Linkdrops:以太坊上发红包的开源标准
- 关于ElasticSearch (ES)
- 阿里面试必过的 Java 面试参考指南全集
- Typora的初步使用及Markdown语法总结
- 2021年Java面经分享:java基础入门清华大学出版社课后答案