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].如果一棵带点权的有根二叉树满足其所有 ...
随机推荐
- java 获取微信 页面授权 获取用户openid
先调用微信的地址 跳转https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx4b4009c4fce00e0c&redirect ...
- 使用jquery改动表单的提交地址
基本思路: 通过使用jquery选择器得到相应表单的jquery对象,然后使用attr方法改动相应的action 演示样例程序一: 默认情况下,该表单会提交到page_one.html 点击butto ...
- HDFS源码分析心跳汇报之整体结构
我们知道,HDFS全称是Hadoop Distribute FileSystem,即Hadoop分布式文件系统.既然它是一个分布式文件系统,那么肯定存在很多物理节点,而这其中,就会有主从节点之分.在H ...
- cacti 安装和组件添加
安装cacti 步骤 1.准备lamp环境 2.准备所需包:rrdtool(绘图) cacti(安装程序) net-snmpd(数据收集) 3.安装所需库文件 rrdtool所需库文件有: cairo ...
- cacti 主机/网络设备流量监控 图解
1.在配置中找到设备 console —> Device 2.初次添加 cacti 监控主机的时候是没有任何设备的,所以要选择add 添加你要监控的主机 \
- javaScript 深层复制
在工作中遇到了深浅复制的问题,所以详细总结一下: 深复制和浅复制只针对像 Object, Array 这样的复杂对象的.简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级. var o ...
- 小程序框架MpVue踩坑日记(一)
小程序也做了几个小功能模块了,总觉得需要总结一下,踩坑什么的还是得记录一下啊. 好吧,其实是为了方便回顾 首先,说到小程序框架,大家都知道wepy,不过,我是没用过 美团开发团队到mpvue到是个实在 ...
- Linux 批量替换的一种实现方式
替换某目录下所有文件中的某个字符: sed -i 's/origin_str/new_str/g' `grep origin_str -rl ./` origin_str:被替换的字符串: new_s ...
- ssh无密码登陆屌丝指南
[0]写在前面 由于ssh 实现的是免密码登陆,大致步骤是: 0.1) client通过ssh登陆到server: 0.2) server检查家目录下的.ssh文件, 并发送公钥文件 authoriz ...
- Unix高级环境编程—进程控制(一)
一.函数fork #include<unistd.h> pid_t fork(void) ...