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].如果一棵带点权的有根二叉树满足其所有 ...
随机推荐
- pm2 服务崩溃 Error: bind EADDRINUSE
pm2 服务崩溃 Error: bind EADDRINUSE 发布于 1 年前 作者 zhujun24 2444 次浏览 来自 问答 Error: bind EADDRINUSE 0.0.0 ...
- Android:实现两个Activity相互切换而都不走onCreate()
本文要实现的目的是: 有3个Activity: A,B,C.从A中能够进入B,B中能够进入C.而且B和C之间可能须要多次相互切换,因此不能使用普通的startActivity-finish方式,由于又 ...
- Unix高级环境编程—进程控制(一)
一.函数fork #include<unistd.h> pid_t fork(void) ...
- 【BZOJ2096】[Poi2010]Pilots 双指针+单调队列
[BZOJ2096][Poi2010]Pilots Description Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串, ...
- HttpClient 访问 https 出现peer can't
package util; import java.security.cert.CertificateException; import javax.net.ssl.SSLContext;import ...
- AsyncTask==Handler+Thread对比使用说明
AsyncTask能够合理且轻松使用UI线程,该类允许执行后台操作和发送结果到UI线程而不需要操作threads或handlers. AsyncTask是针对Thread和Handler代替而封装好的 ...
- 流畅的python学习笔记:第十一章:抽象基类
__getitem__实现可迭代对象.要将一个对象变成一个可迭代的对象,通常都要实现__iter__.但是如果没有__iter__的话,实现了__getitem__也可以实现迭代.我们还是用第一章扑克 ...
- ABAP 调用webservice 错误
错误:1.soamanager 配置端口错误: 调整端口后报错: java端回复: 嗯 有问题了我待会儿看看应该是数据有问题
- Machine Learning No.11: Recommender System
1. Content based Problem formulation Content Based Recommendations: 2. collaborative filtering algor ...
- 使用 HTML5 的 IndexedDB API
1. [代码]判断是否支持 IndexedDB var indexedDB = window.indexedDB || window.webkitIndexedDB || window.moz ...