题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3625

   http://codeforces.com/contest/438/problem/E

开方:https://blog.csdn.net/kscla/article/details/79356786

不过还是不会二次剩余。

也不知道为什么取了 G(x)-B(x)=0 而不是 G(x)+B(x)=0。

式子是  B(x) = ( A(x) + G2(x) ) / 2*G(x) ,但写的时候这样比较方便:

令 D(x) = b-1(x) , 则 B(x) =( a(x) * D(x) + b(x) ) / 2;

可以开一个 C(x) 表示 a(x) ,这样就不用动 a 数组了;因为加法和乘法都可以在系数上做,所以也可以不用把 b 数组 ntt 了。

getinv 的时候可以用 A 和 B 表示 a 和 b ,这样就不用把 a 数组和 b 数组 ntt 了。

  F(x) = D(x) * F2(x) + 1 ;其中+1是因为D没有常数项,所以不+1的话F也没有常数项,但 f [0]=0。

  F(x) = ( 1+ sqrt(1-4*D(x)) ) / 2*D(x) ,这里要取减号,因为D没有常数项,如果分子剩下了常数项,就会除出余数,不太对。

  写成  F(x) = 2 / 2*D(x)*sqrt( 1+4*D(x) )  比较方便。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e5+,M=N<<,mod=;
int a[M],b[M],A[M],B[M],C[M],D[M],len,r[M],inv2;
int rdn()
{
int ret=;bool fx=;char ch=getchar();
while(ch>''||ch<''){if(ch=='-')fx=;ch=getchar();}
while(ch>=''&&ch<='') ret=ret*+ch-'',ch=getchar();
return fx?ret:-ret;
}
void upd(int &x){x>=mod?x-=mod:;}
int pw(int x,int k)
{int ret=;while(k){if(k&)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=;}return ret;}
void ntt(int *a,bool fx)
{
for(int i=;i<len;i++)
if(i<r[i])swap(a[i],a[r[i]]);
for(int R=;R<=len;R<<=)
{
int Wn=pw( ,(mod-)/R );
if(fx) Wn=pw( Wn,mod- );
for(int i=,m=R>>;i<len;i+=R)
for(int j=,w=;j<m;j++,w=(ll)w*Wn%mod)
{
int x=a[i+j], y=(ll)w*a[i+m+j]%mod;
a[i+j]=x+y; upd(a[i+j]);
a[i+m+j]=x+mod-y; upd(a[i+m+j]);
}
}
if(!fx)return; int inv=pw(len,mod-);
for(int i=;i<len;i++)a[i]=(ll)a[i]*inv%mod;
}
void getinv(int n,int *a,int *b)
{
if(n==){b[]=pw(a[],mod-);return;}
getinv(n>>,a,b);
len=n<<;
for(int i=;i<len;i++)r[i]=(r[i>>]>>)+((i&)?len>>:);
for(int i=;i<n;i++)A[i]=a[i],B[i]=b[i];
ntt(A,); ntt(B,);
for(int i=;i<len;i++)A[i]=(ll)A[i]*B[i]%mod*B[i]%mod;
ntt(A,);
for(int i=;i<n;i++)b[i]=b[i]<<,upd(b[i]);
for(int i=;i<n;i++)b[i]=b[i]+mod-A[i],upd(b[i]);
for(int i=;i<len;i++)A[i]=,B[i]=;//i=0!!! or can't clear after a total getinv
}
void getsqr(int n,int *a,int *b)
{
if(n==){b[]=;return;}
getsqr(n>>,a,b);
for(int i=;i<n;i++)C[i]=a[i];
getinv(n,b,D);
len=n<<;
for(int i=;i<len;i++)r[i]=(r[i>>]>>)+((i&)?len>>:);
ntt(C,); ntt(D,);
for(int i=;i<len;i++) D[i]=(ll)C[i]*D[i]%mod;
ntt(D,);
for(int i=;i<n;i++)b[i]=(ll)(D[i]+b[i])*inv2%mod;
for(int i=;i<len;i++) C[i]=D[i]=;//
}
int main()
{
int n,m; n=rdn(); m=rdn(); inv2=pw(,mod-);
for(int i=;i<=n;i++)a[rdn()]=mod-;
a[]++;
for(n=;n<=m;n<<=);
getsqr(n,a,b); b[]++; upd(b[]); for(int i=;i<n;i++)a[i]=;//<n is enough
getinv(n,b,a);
for(int i=;i<=m;i++)a[i]<<=,upd(a[i]);
for(int i=;i<=m;i++)printf("%d\n",a[i]);
return ;
}

bzoj 3625(CF 438E)The Child and Binary Tree——多项式开方的更多相关文章

  1. CF 438E The Child and Binary Tree

    BZOJ 3625 吐槽 BZOJ上至今没有卡过去,太慢了卡得我不敢交了…… 一件很奇怪的事情就是不管是本地还是自己上传数据到OJ测试都远远没有到达时限. 本题做法 设$f_i$表示权值为$i$的二叉 ...

  2. Codeforces 438E. The Child and Binary Tree 多项式,FFT

    原文链接www.cnblogs.com/zhouzhendong/p/CF438E.html 前言 没做过多项式题,来一道入门题试试刀. 题解 设 $a_i$ 表示节点权值和为 $i$ 的二叉树个数, ...

  3. [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)

    [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...

  4. BZOJ #3625 CF #438E 小朋友和二叉树

    清真多项式题 BZOJ #3625 codeforces #438E 题意 每个点的权值可以在集合$ S$中任取 求点权和恰好为$[1..n]$的不同的二叉树数量 数据范围全是$ 10^5$ $ So ...

  5. Codeforces 250 E. The Child and Binary Tree [多项式开根 生成函数]

    CF Round250 E. The Child and Binary Tree 题意:n种权值集合C, 求点权值和为1...m的二叉树的个数, 形态不同的二叉树不同. 也就是说:不带标号,孩子有序 ...

  6. 【CF】438E. The Child and Binary Tree

    http://codeforces.com/contest/438/problem/E 题意:询问每个点权值在 $c_1, c_2, ..., c_m$ 中,总权值和为 $s$ 的二叉树个数.请给出每 ...

  7. Codeforces 438E The Child and Binary Tree - 生成函数 - 多项式

    题目传送门 传送点I 传送点II 传送点III 题目大意 每个点的权值$c\in {c_{1}, c_{2}, \cdots, c_{n}}$,问对于每个$1\leqslant s\leqslant ...

  8. Codeforces 438E The Child and Binary Tree [DP,生成函数,NTT]

    洛谷 Codeforces 思路 看到计数和\(998244353\),可以感觉到这是一个DP+生成函数+NTT的题. 设\(s_i\)表示\(i\)是否在集合中,\(A\)为\(s\)的生成函数,即 ...

  9. 【CF438E】The Child and Binary Tree(多项式运算,生成函数)

    [CF438E]The Child and Binary Tree(多项式运算,生成函数) 题面 有一个大小为\(n\)的集合\(S\) 问所有点权都在集合中,并且点权之和分别为\([0,m]\)的二 ...

随机推荐

  1. Oracle常用的OCI函数

    一. Oracle oci工具包安装: $ORACLE_HOME\BIN:执行文件和help文件 $ORACLE_HOME\OCI\INCLUDE:头文件 $ORACLE_HOME\OCI\LIB\B ...

  2. 【鸟哥的Linux私房菜】笔记1

    Linux是什么 从操作系统与cpu架构关系到linux  Richard Mathew Stallman GPL 关于GNU计划 Linux的发展 Linux的核心版本 Linux的特色 Linux ...

  3. Listening Carefully SP1403S

    Listening Carefully仔细聆听When people talk, listen completely. Most people never listen. ―Ernest Heming ...

  4. Java 访问修饰符总结

    Java中的访问修饰符 Java面向对象的基本思想之一是封装细节并且公开接口. Java语言采用访问控制修饰符来封装类及类的方法和属性的访问权限,从而向使用者暴露接口.隐藏细节. Java访问控制分为 ...

  5. Go 语言基础知识

    0. Go语言书单 1. 文本注释 // 单行注释 /* */ 多行注释 2. 变量赋值 = 变量赋值 := 声明变量并赋值 3. 变量定义 var name string var age int v ...

  6. Eclipse 换主题、皮肤、配色,换黑色主题护眼

    Eclipse写android代码时,默认的文本和框架都是白色,长时间使用,显得过于刺眼.这里介绍三种方法换黑色护眼配色. 1.系统设置里更改 2.从Eclipse Marketplace里下载主题 ...

  7. Eclipse4.2安装样式插件

    1.插件地址 http://eclipse-color-theme.github.com/update 点击Eclipse菜单 Help>>Install New Software... ...

  8. 【bzoj1925】地精部落[SDOI2010](dp)

    题目传送门:1925: [Sdoi2010]地精部落 这道题,,,首先可以一眼看出他是要我们求由1~n的排列组成,并且抖来抖去的序列的方案数.然后再看一眼数据范围,,,似乎是O(n^2)的dp?然后各 ...

  9. ES6-let命令

    let命令 用于声明变量,但是声明的变量只能在let命令所在的代码块内有效, { let a = 10; var b = 1; } 其中,a在代码块的外部是调用不到的.对于for循环的计数器里面,就很 ...

  10. 如何手动添加 WIFI 网络步骤

    电脑手动添加WiFi网络步骤: 1.右键控制面板 2.进入控制面板 3.进入网络和Internet,点击设置新的连接或网络 4.点击手动连接到无线网络 5.输入网络SSID及秘钥 若需要自动连接请勾选 ...