BZOJ 3684 大朋友与多叉树 多项式求幂/求exp+拉格朗日反演
来源:互联网 发布:短信群发软件下载 编辑:程序博客网 时间:2024/06/06 10:59
题意:链接
方法:多项式求幂+拉格朗日反演。
解析:
毒瘤题最后一个。
首先先写几个公式(勿问证明)
Fk(x)=exp(k∗ln(F(X)))
若F(G(x))=G(F(x))=x
则称F(x)与G(x)互为复合逆
若F(x)为G(x)的复合逆
[xn]F(x)表示F(x)的n次方项系数
则有[xn]F(x)=1n[xn−1](xG(x))n
推广
[xn]H(F(x))=1n[xn−1]H′(x)(xG(x))n
然而这题用不到推广,别怕- -!
我们显然可以搞出来d的生成函数。
我们设F(x)是根节点点权的生成函数。
则
F(x)=∑i∈DFi(x)+x
+x代表他是叶节点时。
再搞出来D中元素的生成函数C(x)
则
F(x)=C(F(x))+x
设G(x)=x−C(x)
则有
G(F(x))=x
所以F(x)是G(x)的复合逆。
于是有
[xn]F(x)=1n[xn−1](xG(x))n
如果细心一点发现,(xG(x)) 上下可以同约一个x,这样的话可以保证这个东西是可求ln的,因为常数项就变成1了,所以我们不必进行一些关于常数项的转化什么的。
出题人良心!
求exp怎么求呢?
无脑倍增….
上图是牛顿迭代。
然后我们带进上图的式子。
然后就可以无脑倍增了…
神奇!
代码:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N 262244#define mod 950009857using namespace std;typedef long long ll;int s,m,l;int rev[N];ll G[N],G_inv[N],G_inv_n[N],G_inv_dao[N],G_inv_ln[N];ll inv[N];void init(){ inv[1]=1; for(int i=2;i<l;i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod;}ll Quick_Power(ll x,ll y,ll MOD){ ll ret=1; while(y) { if(y&1)ret=(ret*x)%MOD; x=(x*x)%MOD; y>>=1; } return ret;}void NTT(ll *a,int n,int f){ for(int i=0;i<n;i++)if(i<rev[i])swap(a[i],a[rev[i]]); for(int h=2;h<=n;h<<=1) { ll wn=Quick_Power(7,(mod-1)/h,mod); for(int i=0;i<n;i+=h) { ll w=1; for(int j=0;j<(h>>1);j++,w=w*wn%mod) { ll t=a[i+j+(h>>1)]*w%mod; a[i+j+(h>>1)]=((a[i+j]-t)%mod+mod)%mod; a[i+j]=(a[i+j]+t)%mod; } } } if(f==-1) { for(int i=1;i<(n>>1);i++)swap(a[i],a[n-i]); ll inv=Quick_Power(n,mod-2,mod); for(int i=0;i<n;i++)a[i]=(long long)a[i]*inv%mod; }}void Get_Inv(ll *a,ll *b,int n){ static ll temp[N]; if(n==1) { b[0]=Quick_Power(a[0],mod-2,mod); return; } Get_Inv(a,b,n>>1); memcpy(temp,a,sizeof(a[0])*n); memset(temp+n,0,sizeof(a[0])*n); int m=n,L=0,nn=n; for(n=1;n<=m;n<<=1)L++; for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1)); NTT(temp,n,1),NTT(b,n,1); for(int i=0;i<n;i++) temp[i]=b[i]*(((2ll-temp[i]*b[i]%mod)%mod+mod)%mod)%mod; NTT(temp,n,-1); for(int i=0;i<(n>>1);i++)b[i]=temp[i]; memset(b+nn,0,sizeof(b[0])*nn); n=nn;}void Get_Ln(ll *a,ll *b,int n){ static ll a_dao[N],a_inv[N]; for(int i=1;i<=n;i++) a_dao[i-1]=a[i]*i%mod; a_dao[n]=0; Get_Inv(a,a_inv,n); int m=n,L=0; for(n=1;n<=m;n<<=1)L++; for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1)); NTT(a_inv,n,1),NTT(a_dao,n,1); for(int i=0;i<n;i++) b[i]=a_inv[i]*a_dao[i]%mod; NTT(b,n,-1); for(int i=n-1;i>=1;i--) b[i]=b[i-1]*inv[i]%mod; b[0]=0; memset(b+m,0,sizeof(b[0])*m); memset(a_dao,0,sizeof(a_dao[0])*n); memset(a_inv,0,sizeof(a_inv[0])*n);}void Get_Exp(ll *a,ll *b,int n){ static ll temp[N]; if(n==1) { b[0]=1; return; } Get_Exp(a,b,n>>1); memset(temp,0,sizeof(a[0])*(n<<1)); Get_Ln(b,temp,n); for(int i=0;i<n;i++) temp[i]=((i==0)+mod-temp[i]+a[i])%mod; int m=n,L=0,nn=n; for(n=1;n<=m;n<<=1)L++; for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1)); NTT(b,n,1),NTT(temp,n,1); for(int i=0;i<n;i++) b[i]=b[i]*temp[i]%mod; NTT(b,n,-1); memset(b+nn,0,sizeof(b[0])*nn); n=nn;}int main(){ scanf("%d%d",&s,&m); G[0]=1; for(int i=1;i<=m;i++) { ll x; scanf("%lld",&x); G[x-1]=mod-1; } for(l=1;l<=s;l<<=1); init(); Get_Inv(G,G_inv,l); Get_Ln(G_inv,G_inv_ln,l); for(int i=0;i<l;i++) G_inv_ln[i]=G_inv_ln[i]*s%mod; Get_Exp(G_inv_ln,G_inv_n,l); printf("%lld\n",G_inv_n[s-1]*Quick_Power(s,mod-2,mod)%mod);}
0 2
- BZOJ 3684 大朋友与多叉树 多项式求幂/求exp+拉格朗日反演
- BZOJ 3684 大朋友和多叉树 FFT+拉格朗日反演
- 求多项式的值与求幂的快速算法
- BZOJ 3456 城市规划 多项式求ln
- bzoj 3456: 城市规划 NTT+多项式求逆
- 多项式求逆 与 多项式开方
- 求朋友
- bzoj 4555:[Tjoi2016&Heoi2016]求和 多项式求逆
- [多项式求逆 模板题] BZOJ 4555 [Tjoi2016&Heoi2016]求和
- bzoj 3456: 城市规划 (NTT+多项式求逆)
- [生成函数][NTT][多项式求逆]BZOJ 3456: 城市规划
- bzoj 3684: 大朋友和多叉树 生成函数
- BZOJ 3684 大朋友和多叉树(生成函数+FFT)
- bzoj 1901 动态求k大值
- 利用堆栈求多项式
- 求多项式的解
- 求n阶勒让德多项式
- 二分法求多项式根
- iOS学习笔记:instancetype关联返回类型
- Volley, HttpUtils,省略findViewById()和点击事件的.setOnClickListener(this);,DbUtils
- 测试分页接口
- ViewPager与SwipeRefreshLayout冲突问题
- Android之Json转换利器Gson之实例一-简单对象转化和带泛型的List转化
- BZOJ 3684 大朋友与多叉树 多项式求幂/求exp+拉格朗日反演
- HDU 5441 Travel(求各个集合里的秩能组合多少对,只能在一个集合里组合)
- 关于json一片号的文章,转载来收藏一下
- web_custom_request 例子
- 如果浏览器不支持 cookie 该怎么办?
- maven 工程学习
- 【面试】-百度外卖后端开发工程师
- UVA 10269 Adventure of Super Mario 最短路
- 显示win32控制台