zoukankan      html  css  js  c++  java
  • 【bzoj3684】 大朋友和多叉树 生成函数+多项式快速幂+拉格朗日反演

    这题一看就觉得是生成函数的题...

    我们不妨去推下此题的生成函数,设生成函数为$F(x)$,则$[x^s]F(x)$即为答案。

    根据题意,我们得到 $F(x)=x+sum_{i∈D} F^i(x)$,其中前面单独出现的$x$可以理解为空树的情况。

    如果$i$的范围很小,那么我们就可以用求根公式去解多项式方程23333。

    然而考虑到$i$最大为$10^5$,根据阿贝尔定理,无根式解,所以不能用此方法。

    我们对原先的式子做一个移项,得$F(x)-sum_{i∈D} F^i(x)=x$。

    我们构造函数$G(x)=x-sum_{i∈D}x^i$。

    不难发现$G(F(x))=F(x)-sum_{i∈D}F^i(x)=x$。也就是说$F(x)$和$G(x)$互为反函数。

    然后我们现在已知$G(x)$,要求$F(x)$使得$G(F(x))=x$。也就是求$G(x)$的复合逆。

    根据拉格朗日反演,若$G(F(x))=x$,则有$[x^s]F(x)=dfrac{1}{s}[x^{-1}]dfrac{1}{G^s(x)}$。

    然后,我们对式子乘上$x^s$,得到$[x^s]F(x)=dfrac{1}{s}[x^{s-1}](dfrac{1}{G(x)})^s$。

    然后后面就是多项式快速幂了。

     

      1 #include<bits/stdc++.h>
      2 #define G 7
      3 #define L long long
      4 #define MOD 950009857
      5 #define inv(x) pow_mod(x,MOD-2)
      6 #define M 1<<18
      7 using namespace std;
      8 
      9 L pow_mod(L x,L k){
     10     L ans=1;
     11     while(k){
     12         if(k&1) ans=ans*x%MOD;
     13         k=k>>1; x=x*x%MOD;
     14     }
     15     return ans;
     16 }
     17 
     18 void change(L a[],int n){
     19     for(int i=0,j=0;i<n-1;i++){
     20         if(i<j) swap(a[i],a[j]);
     21         int k=n>>1;
     22         while(j>=k) j-=k,k>>=1;
     23         j+=k;
     24     }
     25 }
     26 void NTT(L a[],int n,int on){
     27     change(a,n);
     28     for(int h=2;h<=n;h<<=1){
     29         L wn=pow_mod(G,(MOD-1)/h);
     30         for(int j=0;j<n;j+=h){
     31             L w=1;
     32             for(int k=j;k<j+(h>>1);k++){
     33                 L u=a[k],t=a[k+(h>>1)]*w%MOD;
     34                 a[k]=(u+t)%MOD;
     35                 a[k+(h>>1)]=(u-t+MOD)%MOD;
     36                 w=w*wn%MOD;
     37             }
     38         }
     39     }
     40     if(on==-1){
     41         L inv=inv(n);
     42         for(int i=0;i<n;i++) a[i]=a[i]*inv%MOD;
     43         reverse(a+1,a+n);
     44     }
     45 }
     46 
     47 void getinv(L a[],L b[],int n){
     48     if(n==1) return void(b[0]=inv(a[0]));
     49     static L A[M],B[M];
     50     memset(A,0,sizeof(A)); memset(B,0,sizeof(B));
     51     getinv(a,B,n>>1);
     52     for(int i=0;i<n;i++) A[i]=a[i];
     53     NTT(A,n<<1,1); NTT(B,n<<1,1);
     54     for(int i=0;i<(n<<1);i++) b[i]=(2*B[i]-A[i]*B[i]%MOD*B[i]%MOD+MOD)%MOD;
     55     NTT(b,n<<1,-1);
     56     for(int i=0;i<n;i++) b[n+i]=0;
     57 }
     58 
     59 void qiudao(L a[],L b[],int n){
     60     memset(b,0,sizeof(b));
     61     for(int i=1;i<n;i++) b[i-1]=i*a[i]%MOD;
     62 }
     63 void jifen(L a[],L b[],int n){
     64     memset(b,0,sizeof(b));
     65     for(int i=0;i<n;i++) b[i+1]=a[i]*pow_mod(i+1,MOD-2)%MOD;
     66 }
     67 
     68 void getln(L a[],L b[],int n){
     69     static L c[M],d[M];
     70     memset(c,0,M<<3); memset(d,0,M<<3);
     71     qiudao(a,c,n); getinv(a,d,n);
     72     NTT(c,n<<1,1); NTT(d,n<<1,1);
     73     for(int i=0;i<(n<<1);i++) c[i]=c[i]*d[i]%MOD;
     74     NTT(c,n<<1,-1);
     75     jifen(c,b,n);
     76 }
     77 
     78 void getexp(L a[],L b[],int n){
     79     if(n==1){b[0]=1; return;}
     80     static L lnb[M]; memset(lnb,0,M<<3);
     81     getexp(a,b,n>>1); getln(b,lnb,n);
     82     for(int i=0;i<n;i++) lnb[i]=(a[i]-lnb[i]+MOD)%MOD;
     83     lnb[n]=0;
     84     lnb[0]=(lnb[0]+1)%MOD;
     85     NTT(lnb,n<<1,1); NTT(b,n<<1,1);
     86     for(int i=0;i<(n<<1);i++) b[i]=b[i]*lnb[i]%MOD;
     87     NTT(b,n<<1,-1);
     88     for(int i=0;i<n;i++) b[i+n]=0;
     89 }
     90 
     91 L g[M]={0},f[M]={0};
     92 
     93 void pow_mod(L a[],L b[],int n,int k){
     94     memset(b,0,M<<3);
     95     getln(a,b,n);
     96     for(int i=0;i<n;i++) a[i]=b[i]*k%MOD;
     97     memset(b,0,M<<3);
     98     getexp(a,b,n);
     99 }
    100 
    101 int main(){
    102     int n,m;
    103     scanf("%d%d",&n,&m);
    104     for(int i=1;i<=m;i++){
    105         int x; scanf("%d",&x);
    106         g[x-1]=-1;
    107     }
    108     g[0]=1;
    109     int nn=1;while(nn<n) nn<<=1;
    110     getinv(g,f,nn);
    111     memset(g,0,sizeof(g)); 
    112     pow_mod(f,g,nn,n);
    113     L ans=inv(n)*g[n-1]%MOD;
    114     cout<<ans<<endl;
    115 }
  • 相关阅读:
    Web Client Software Factory 开发路线图
    Castle ActiveRecord Hands On Lab(1):基本数据访问
    古代武侠武功与现代软件开发
    微软Code Snippet Designer Alpha版发布了
    MSDN WebCast网站全新改版
    AJAX,只是一种过渡技术吗?
    中文网站排行榜:博客园位居博客类16名
    ASP.NET AJAX JavaScript 类浏览器
    .NET开源项目介绍及资源推荐:序
    微软发布WF教程及大量示例
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9097449.html
Copyright © 2011-2022 走看看