CF 438 E & bzoj 3625 小朋友和二叉树 —— 多项式开方
题目:http://codeforces.com/contest/438/problem/E
https://www.lydsy.com/JudgeOnline/problem.php?id=3625
多项式开方...
注意传进 sqt 中的模数应该是2的整数次幂,所以先补到 >=m ;
还要注意每次一定要先递归或进入别的子函数,再算 rev 数组,否则会被覆盖!
最重要的是 lim < n+n 而不是 <= ,否则会把数组撑大一倍(于是 (1<<18) 会RE),而如果真的把数组开到 (1<<19),又会因为进行 NTT 的长度变成两倍而(在bzoj上) TLE ...
想想,因为一开始已经是 lim <= m,所以 lim 一定是偏大的,也就是传进去的 n 并不是顶到的上界,也就不用必须 <= ;
而传进去的 n 本身是一个2的整数次幂,所以 <= 会纯粹的增大一倍;(所以直接写成 n>>1 就好了)
注意细节啊...
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const xn=(<<)+,mod=,g=;
int n,m,c[xn],t[xn],tt[xn],rev[xn],sc[xn],inv2,f[xn];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
ll pw(ll a,int b)
{
ll ret=;
for(;b;b>>=,a=(a*a)%mod)if(b&)ret=(ret*a)%mod;
return ret;
}
int upt(int x){while(x>=mod)x-=mod; while(x<)x+=mod; return x;}
void ntt(int *a,int tp,int lim)
{
for(int i=;i<lim;i++)
if(i<rev[i])swap(a[i],a[rev[i]]);
for(int mid=;mid<lim;mid<<=)
{
int wn=pw(g,(mod-)/(mid<<));
if(tp==-)wn=pw(wn,mod-);
for(int j=,len=(mid<<);j<lim;j+=len)
{
int w=;
for(int k=;k<mid;k++,w=(ll)w*wn%mod)
{
int x=a[j+k],y=(ll)w*a[j+mid+k]%mod;
a[j+k]=upt(x+y); a[j+mid+k]=upt(x-y);
}
}
}
if(tp==)return; int inv=pw(lim,mod-);
for(int i=;i<lim;i++)a[i]=(ll)a[i]*inv%mod;
}
void inv(int *a,int *b,int n)
{
if(n==){b[]=pw(a[],mod-); return;}
inv(a,b,n>>);
int lim=,l=;
while(lim<n+n)lim<<=,l++;//<= (1<<19) TLE
for(int i=;i<lim;i++)rev[i]=((rev[i>>]>>)|((i&)<<(l-)));//after inv!!!
for(int i=;i<n;i++)tt[i]=a[i];
for(int i=n;i<lim;i++)tt[i]=;
ntt(tt,,lim); ntt(b,,lim);
for(int i=;i<lim;i++)b[i]=upt(((ll)-(ll)tt[i]*b[i])%mod*b[i]%mod);
ntt(b,-,lim);
for(int i=n;i<lim;i++)b[i]=;
}
void sqt(int *a,int *b,int n)
{
if(n==){b[]=; return;}
sqt(a,b,n>>);
int lim=,l=;
while(lim<n+n)lim<<=,l++;//<= (1<<19) TLE
for(int i=;i<lim;i++)t[i]=;
inv(b,t,n);
for(int i=;i<lim;i++)rev[i]=((rev[i>>]>>)|((i&)<<(l-)));//after inv!!!
for(int i=;i<n;i++)tt[i]=a[i];
for(int i=n;i<lim;i++)tt[i]=;
ntt(b,,lim); ntt(tt,,lim); ntt(t,,lim);
for(int i=;i<lim;i++)b[i]=((ll)b[i]+(ll)tt[i]*t[i])%mod*inv2%mod;
ntt(b,-,lim);
for(int i=n;i<lim;i++)b[i]=;
}
int main()
{
n=rd(); m=rd(); inv2=pw(,mod-);
for(int i=,x;i<=n;i++)x=rd(),c[x]++;
int lim=; while(lim<=m)lim<<=;//m
for(int i=;i<lim;i++)c[i]=((-(ll)*c[i])%mod+mod)%mod;//!1-4*c[i]! //(ll)!!
c[]=;//1+!!
sqt(c,sc,lim);//lim
sc[]++; sc[]=upt(sc[]);
inv(sc,f,lim);
for(int i=;i<=m;i++)printf("%d\n",upt(f[i]<<));
return ;
}
CF 438 E & bzoj 3625 小朋友和二叉树 —— 多项式开方的更多相关文章
- bzoj 3625小朋友和二叉树 多项式求逆+多项式开根 好题
题目大意 给定n种权值 给定m \(F_i表示权值和为i的二叉树个数\) 求\(F_1,F_2...F_m\) 分析 安利博客 \(F_d=F_L*F_R*C_{mid},L+mid+R=d\) \( ...
- BZOJ 3625:小朋友和二叉树 多项式开根+多项式求逆+生成函数
生成函数这个东西太好用了~ code: #include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s&q ...
- [Codeforces438E][bzoj3625] 小朋友和二叉树 [多项式求逆+多项式开根]
题面 传送门 思路 首先,我们把这个输入的点的生成函数搞出来: $C=\sum_{i=0}^{lim}s_ix^i$ 其中$lim$为集合里面出现过的最大的数,$s_i$表示大小为$i$的数是否出现过 ...
- [BZOJ3625][Codeforces Round #250]小朋友和二叉树 多项式开根+求逆
https://www.lydsy.com/JudgeOnline/problem.php?id=3625 愉快地列式子.设\(F[i]\)表示权值为\(i\) 的子树的方案数,\(A[i]\)为\( ...
- BZOJ #3625 CF #438E 小朋友和二叉树
清真多项式题 BZOJ #3625 codeforces #438E 题意 每个点的权值可以在集合$ S$中任取 求点权和恰好为$[1..n]$的不同的二叉树数量 数据范围全是$ 10^5$ $ So ...
- BZOJ 3625: [Codeforces Round #250]小朋友和二叉树
3625: [Codeforces Round #250]小朋友和二叉树 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 304 Solved: 13 ...
- [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)
[BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...
- 「BZOJ 3645」小朋友与二叉树
「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...
- 【bzoj3625】【xsy1729】小朋友和二叉树
[bzoj3625]小朋友与二叉树 题意 我们的小朋友很喜欢计算机科学,而且尤其喜欢二叉树. 考虑一个含有n个互异正整数的序列c[1],c[2],...,c[n].如果一棵带点权的有根二叉树满足其所有 ...
随机推荐
- sql 注入 与解决
package cn.itcast.jdbc; import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLExce ...
- checkStyle使用具体解释
简单介绍 checkStyle是一款代码格式检查工具.它依据设置好的编码规则来自己主动检查代码.比方命名规范,文件长度.代码行长度等等.代码检查工具是保证项目代码质量.统一编码风格的一种重要途径.本篇 ...
- typeof 与 instanceof 区别
typeof typeof 是一元运算符,返回值是字符串,且只能是number,string,boolean,object,function,undefined typeof用来判断一个值是否存在 i ...
- C#高级编程 第十五章 反射
(二)自定义特性 使自定义特性非常强大的因素时使用反射,代码可以读取这些元数据,使用它们在运行期间作出决策. 1.编写自定义特性 定义一个FieldName特性: [AttributeUsage(At ...
- Mybatis之基本简介
一.Mybatis简介 MyBatis 是一个可以自定义SQL.存储过程和高级映射的持久层框架.MyBatis 摒除了大部分的JDBC代码.手工设置参数和结果集重获.MyBatis 只使用简单的XML ...
- centos安装php5.6
配置yum源 追加CentOS 6.5的epel及remi源. # rpm -Uvh http://ftp.iij.ad.jp/pub/linux/fedora/epel/6/x86_64/epel- ...
- 运用<ul><li>做导航栏
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Java for LeetCode 120 Triangle
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...
- 获取原生的DOM方式,DIY脚手架,vue-cli的使用
一 . 获取原生的DOM的方式 在js中,我们可以通过id, class 或者标签获取DOM元素,vue中也为我们提供了获取原生DOM的方法,就是给标签或者组件添加 ref 属性,通过 this.$r ...
- iOS本地数据存取,看这里就够了
本文授权转载,作者:hosea_zhou(简书) 应用沙盒 1)每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒 2) ...