这个题意说人话就是:一棵带标号的有根树,编号满足堆性质,根节点有$x$个儿子是叶子($x\in A$),另外的$2$个儿子也是这样的一棵树,求不同的树的个数

设$f_n$为答案,枚举那两棵子树的大小$i,j$,那么$f_i=\frac12\sum\limits_{1\leq j,k\lt i}[i-1-j-k\in A]\binom{i-1}j\binom{i-1-j}kf_jf_k$,$f_1=1$,直接做是$O(n^3)$的

把组合数拆开,记$a_i=[i\in A]\frac1{i!},f'_i=\frac{f_i}{i!},g_i=\sum\limits_{j+k=i}f'_jf'_k$,那么$f'_i=\frac1{2i}\sum\limits_{j+k=i-1}a_jg_k$,按照这个直接做,每次更新$g$,时间复杂度为$O(n^2)$

因为$f,g$的递推式都是卷积,所以考虑分治FFT,这种类CDQ分治的分治FFT主要解决形如$f_i=\sum\limits_{j+k=i}g_jh_k$的递推式,其中$g,h$中至少一个与$f$有关

如果当前分治到$[l,r]$,先递归进$[l,mid]$,然后算递推式中$j\in[l,mid],i\in[mid+1,r]$的部分,一次卷积就可以了

需要注意的是如果$g,h$都与$f$有关,那么我们还要处理$j,k\in[l,mid],i\in[mid+1,r]$的情况,但因为是分治结构,所以这种情况只会在$l=1$时出现,于是只需在$l\gt1$时再做一次即可,如果$g=h$那么直接把答案$\times2$就行了

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
int mul(int a,int b){return(ll)a*b%mod;}
int ad(int a,int b){return(a+b)%mod;}
int de(int a,int b){return(a-b)%mod;}
void inc(int&a,int b){(a+=b)%=mod;}
int pow(int a,int b){
	int s=1;
	while(b){
		if(b&1)s=mul(s,a);
		a=mul(a,a);
		b>>=1;
	}
	return s;
}
int rev[524288],N,iN;
void pre(int n){
	int i,k;
	for(N=1,k=0;N<n;N<<=1)k++;
	for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
	iN=pow(N,mod-2);
}
void ntt(int*a,int on){
	int i,j,k,t,w,wn;
	for(i=0;i<N;i++){
		if(i<rev[i])swap(a[i],a[rev[i]]);
	}
	for(i=2;i<=N;i<<=1){
		wn=pow(3,on==1?(mod-1)/i:mod-1-(mod-1)/i);
		for(j=0;j<N;j+=i){
			w=1;
			for(k=0;k<i>>1;k++){
				t=mul(a[i/2+j+k],w);
				a[i/2+j+k]=de(a[j+k],t);
				a[j+k]=ad(a[j+k],t);
				w=mul(w,wn);
			}
		}
	}
	if(on==-1){
		for(i=0;i<N;i++)a[i]=mul(a[i],iN);
	}
}
int ta[524288],tb[524288];
void conv(){
	ntt(ta,1);
	ntt(tb,1);
	for(int i=0;i<N;i++)ta[i]=mul(ta[i],tb[i]);
	ntt(ta,-1);
}
int fac[200010],rfac[200010];
char s[200010];
int a[200010],f[200010],g[200010],inv[400010];
void solve(int l,int r){
	if(l==r)return;
	int mid=(l+r)>>1,i;
	solve(l,mid);
	//f*f->g
	pre(r-l+mid-l+1);
	memset(ta,0,N<<2);
	memset(tb,0,N<<2);
	for(i=1;i<=r-l;i++)ta[i-1]=f[i];
	for(i=l;i<=mid;i++)tb[i-l]=f[i];
	conv();
	if(l>1){
		for(i=mid-l;i<r-l;i++)ta[i]=mul(ta[i],2);
	}
	for(i=1;i<=r-mid;i++)inc(g[i+mid],ta[i+mid-l-1]);
	//a*g->f
	memset(ta,0,N<<2);
	memset(tb,0,N<<2);
	for(i=0;i<r-l;i++)ta[i]=a[i];
	for(i=l;i<=mid;i++)tb[i-l]=g[i];
	conv();
	for(i=1;i<=r-mid;i++)inc(f[i+mid],mul(inv[2*(i+mid)],ta[i+mid-l-1]));
	solve(mid+1,r);
}
int main(){
	int n,i;
	scanf("%d%s",&n,s);
	fac[0]=1;
	for(i=1;i<=n;i++)fac[i]=mul(fac[i-1],i);
	rfac[n]=pow(fac[n],mod-2);
	for(i=n;i>0;i--)rfac[i-1]=mul(rfac[i],i);
	inv[1]=1;
	for(i=2;i<=2*n;i++)inv[i]=-mul(mod/i,inv[mod%i]);
	for(i=0;i<n;i++)a[i]=s[i]=='1'?rfac[i]:0;
	f[1]=1;
	solve(1,n);
	for(i=1;i<=n;i++)printf("%d\n",ad(mul(f[i],fac[i]),mod));
}

[UOJ50]链式反应的更多相关文章

  1. GOOD BYE OI

    大米饼正式退役了,OI给我带来很多东西 我会的数学知识基本都在下面了 博客园的评论区问题如果我看到了应该是会尽力回答的... 这也是我作为一个OIer最后一次讲课的讲稿 20190731 多项式乘法 ...

  2. uoj50【UR#3】链式反应

    题解: 令$a(x)$为破坏死光的$EFG$,$f(x)$为方案的$EGF$:$f(x) = x + \int \  \frac{1}{2} f^2(x) a(x) \  dt$; 注意到$f(0)= ...

  3. 【UOJ#50】【UR #3】链式反应(分治FFT,动态规划)

    [UOJ#50][UR #3]链式反应(分治FFT,动态规划) 题面 UOJ 题解 首先把题目意思捋一捋,大概就是有\(n\)个节点的一棵树,父亲的编号大于儿子. 满足一个点的儿子有\(2+c\)个, ...

  4. nodejs,express链式反应

    链式反应--next() const myexpress = require('express'); const bodyparser = require('body-parser'); var se ...

  5. 【UR #3】链式反应

    http://uoj.ac/problem/50 %炮姐 好博客 树形结构 枚举根节点的儿子是哪两个 然后列出方程: 然后有EGF的影子! 倍增? 泰勒展开可以把未知数从函数里拿出来!并且变成1次项, ...

  6. Monte Carlo方法简介(转载)

    Monte Carlo方法简介(转载)       今天向大家介绍一下我现在主要做的这个东东. Monte Carlo方法又称为随机抽样技巧或统计实验方法,属于计算数学的一个分支,它是在上世纪四十年代 ...

  7. 关于转录组比对STAR软件使用

    参考文章:http://weibo.com/p/23041883f77c940102vbkd?sudaref=passport.weibo.com 软件连接:https://github.com/al ...

  8. [渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序读取相关数据

    这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第七篇:为ASP.NET MVC应用程序 ...

  9. 《Xenogears》(异度装甲)隐含的原型与密码

    <Xenogears>(异度装甲)隐含的原型与密码 X 彩虹按:一种高次元的“生命体”,因“事故”被抓来当成“超能源”,其实那不只是“无限的能源”而已,“它”是有意志的!在我们眼里看来,这 ...

随机推荐

  1. Tinyos 第三版Make系统

    1.make系统安装 cd tools ./Bootstrap ./configure make sudo make install 2.make系统结构 3.第三版Makerules文件部分解析 # ...

  2. oracle链接指定实例

    sqlplus /@ORACLE_SID as sysdba; 其中ORACLE_SID为具体的实例名称, 比如连接到orcl实例就执行命令: sqlplus /@orcl as sysdba; se ...

  3. windows安装linux虚拟机、修改apt源

    记录一下windows安装虚拟机以及初始配置的一些坑. 安装VMware Workstation 直接百度搜索VMware,选择合适的版本下载: 按照一般软件的安装步骤安装VMware Worksta ...

  4. OAuth认证与授权

    什么是OAuth授权?   一.什么是OAuth协议 OAuth(开放授权)是一个开放标准. 允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息. 而这种授权无需将用户提供用户名和密 ...

  5. puppet practice

    目标 试验环境有两台主机(VM)构成,一台是master,一台是agent,完成以下工作: 新建用户newuser; 安装 ubuntu-cloud-keyring package,更改文件/etc/ ...

  6. iOS 取消按钮高亮显示方法

    objective-C 第1种方法: 设置按钮的normal 与 highlighted 一样的图片, 不过如果你也需要selected状态下的图片, 就不能这么做, 这样做在取消选中状态的时候就会显 ...

  7. angular项目中使用Primeng

    1.第一步把依赖添加到项目中 npm install primeng --save npm install @angular/animations --save npm install font-aw ...

  8. CGIC简明教程(转摘)

    CGIC简明教程 本系列的目的是演示如何使用C语言的CGI库“CGIC”完成Web开发的各种要求. *********************************     基础知识       1 ...

  9. v4l

    v4l 2011-11-08 11:01:54|  分类: 默认分类|举报|字号 订阅     第一个部分介绍一些v4l的基本概念和基本方法,利用系统API完成一系列函数以方便后续应用程序的开发和使用 ...

  10. 基于AQS实现的Java并发工具类

    本文主要介绍一下基于AQS实现的Java并发工具类的作用,然后简单谈一下该工具类的实现原理.其实都是AQS的相关知识,只不过在AQS上包装了一下而已.本文也是基于您在有AQS的相关知识基础上,进行讲解 ...