BZOJ3684 great friend and multi-branch tree

Friends and large multi-branch tree

Our great friend liked computer science, and especially like the multi-branch tree. For a positive integer with a point more than the right to have a root tree, if it satisfies such properties, our big friend Ben will be called God: the right to point to the node 1 is a leaf node; for weights greater than any point node 1 u, u children deg number [u] belonging to set D, and u is equal to the point right child node and the right of the point.

Given an integer s, you can find the right value of the root node of God s Ben multi - tree number it? Please refer to the sample in order to better understand what kind of over two tree would be considered different.

We need to know the answers to 950 009 857 ( \ (453 \ Times 21 is 2 ^ {+}. 1 \) value, a prime number) modulo.

Different multi-tree

answer

https://jkloverdcoi.github.io/2019/12/01/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E5%8F%8D%E6%BC%94%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
https://www.cnblogs.com/xiao-ju-ruo-xjr/p/8455362.html

We also start from violence DP. So that f (i) represents a weight of the root node of the tree has a number i, so that G (i, j) represents the sum of the weights of the root node j i forest trees composed of the number of species, it is clear from the following transfer :

\[ f(i) = \sum_{j \in D} g(i, j) \\ f(1) = 1 \\ g(i, j) = \sum_{k = 1}^j g(i - k, j - 1) \cdot f(k) \]

If now represents f (i) with the generating function F. (X), \ (G_J (X) \) represents the g (i, j) of the generating function, not difficult to find \ (G_j (x) = F (x) ^ J \) , then you can get such an equation:

\[ F(x) = x + \sum_{j \in D} F(x)^j \]

Why should a plus x it? DP appears from the boundary conditions f (1) = 1 and f (0) = 0; furthermore meaning of the questions in elements D \ (\ ge 2 \) constant term, but obviously F (x) is 0, then \ (\ sum_ {j \ in D} F (x) ^ j \) is the lowest-order term D is the smallest element, apparently higher than the last entry, so we need to add a x.

But I would not be the solution to this equation, how do? This is the Lagrange inversion theorem the usefulness. This theorem can look at under what conditions.

f (x) and g (x) is the constant term 0, and g (f (x)) = x, then known if g (x), we can quickly find a particular f (x) (the reset request might that \ (\ x ^ n) term), we have:

\[ [x^n]f(x) = \frac{1}{n} [x^{-1}] \left( \frac{1}{g(x)} \right) ^n \]

In fact, if the conditions are constant term 0 meet, f (g (x)) = g (f (x)) = x is true, so the online description of this theorem may be slightly different, in fact, they are equivalent of.

Possible for the above equation you do not understand \ ([x ^ {- 1 }] \) is what to do. Note that g (x) is the constant term is zero, so its inverse does not exist, that there is no Zhengshi can represent \ (\ FRAC {1} {g (x)} \) , this time you need to expand it this field, the introduction of fractional domain. Where all the polynomials can be represented as \ (\ cdots + a _ { - 2} x ^ {- 2} + a _ {- 1} x ^ {- 1} + a_0 + a_1 x + a_2 x ^ 2 + \ cdots \) can be demonstrated in this form can represent all \ (\ FRAC {a (x)} {B (x)} \) , where a (x) and B (x) are Zhengshi. Plainly \ (\ frac {1} { g (x)} \) is a fraction, it has (x ^ - \ {1} ) \ item.

But you want to know how to ask a fraction of \ (x ^ - \ {1 }) items. In fact, we do not need to seek a true fraction, we can end above coefficients g (x) is 0 entries are removed, then normally the inverse element, then a number corresponding to the left. It is about the above equation becomes:

\[ [x^n]f(x) = \frac{1}{n} [x^{dn-1}] \left( \frac{x^d}{g(x)} \right) ^n \]

Wherein \ (D \) represents \ (g (x) \) coefficient prefix \ (0 \) number. This equation is required at \ (\ mod x ^ {dn } \) at g '(x) like the inverse, g' (x) is the polynomial g (x) to the left until a non-zero constant term .

Back to this question is not difficult to find (1) Phase Shift keys to get:

\[ F(x) - \sum_{j \in D} F(x)^j = x \\ G(F(x)) = x \]

So obtained \ (G (x) = x - \ sum_ {j \ in D} x ^ j \) of this polynomial, the problem is solved.

Time complexity \ (O (n-\ log n-) \) .

CO int N=262144;
int omg[2][N],rev[N];
int fac[N],inv[N],ifac[N];

void NTT(poly&a,int dir){
    int lim=a.size(),len=log2(lim);
    for(int i=0;i<lim;++i) rev[i]=rev[i>>1]>>1|(i&1)<<(len-1);
    for(int i=0;i<lim;++i)if(i<rev[i]) swap(a[i],a[rev[i]]);
    for(int i=1;i<lim;i<<=1)
        for(int j=0;j<lim;j+=i<<1)for(int k=0;k<i;++k){
            int t=mul(omg[dir][N/(i<<1)*k],a[j+i+k]);
            a[j+i+k]=add(a[j+k],mod-t),a[j+k]=add(a[j+k],t);
        }
    if(dir==1){
        int ilim=fpow(lim,mod-2);
        for(int i=0;i<lim;++i) a[i]=mul(a[i],ilim);
    }
}
poly operator~(poly a){
    int n=a.size();
    poly b={fpow(a[0],mod-2)};
    if(n==1) return b;
    a.resize(1<<(int)ceil(log2(n)));
    for(int lim=2;lim<2*n;lim<<=1){
        poly c(a.begin(),a.begin()+lim);
        c.resize(lim<<1),NTT(c,0);
        b.resize(lim<<1),NTT(b,0);
        for(int i=0;i<lim<<1;++i) b[i]=mul(2+mod-mul(c[i],b[i]),b[i]);
        NTT(b,1),b.resize(lim);
    }
    return b.resize(n),b;
}
poly log(poly a){
    int n=a.size();
    poly b=~a;
    for(int i=0;i<n-1;++i) a[i]=mul(a[i+1],i+1);
    a.resize(n-1);
    int lim=1<<(int)ceil(log2(2*n-2));
    a.resize(lim),NTT(a,0);
    b.resize(lim),NTT(b,0);
    for(int i=0;i<lim;++i) a[i]=mul(a[i],b[i]);
    NTT(a,1),a.resize(n);
    for(int i=n-1;i>=1;--i) a[i]=mul(a[i-1],inv[i]);
    return a[0]=0,a;
}
poly exp(poly a){
    int n=a.size();
    poly b={1}; // a[0]=0
    if(n==1) return b;
    a.resize(1<<(int)ceil(log2(n)));
    for(int lim=2;lim<2*n;lim<<=1){
        b.resize(lim);poly c=log(b);
        c[0]=add(1+a[0],mod-c[0]);
        for(int i=1;i<lim;++i) c[i]=add(a[i],mod-c[i]);
        c.resize(lim<<1),NTT(c,0);
        b.resize(lim<<1),NTT(b,0);
        for(int i=0;i<lim<<1;++i) b[i]=mul(c[i],b[i]);
        NTT(b,1),b.resize(lim);
    }
    return b.resize(n),b;
}

int main(){
    omg[0][0]=1,omg[0][1]=fpow(7,(mod-1)/N);
    omg[1][0]=1,omg[1][1]=fpow(omg[0][1],mod-2);
    fac[0]=fac[1]=1;
    inv[0]=inv[1]=1;
    ifac[0]=ifac[1]=1;
    for(int i=2;i<N;++i){
        omg[0][i]=mul(omg[0][i-1],omg[0][1]);
        omg[1][i]=mul(omg[1][i-1],omg[1][1]);
        fac[i]=mul(fac[i-1],i);
        inv[i]=mul(mod-mod/i,inv[mod%i]);
        ifac[i]=mul(ifac[i-1],inv[i]);
    }
    int n=read<int>();
    poly g(n);
    for(int m=read<int>();m--;){
        int d=read<int>();
        if(d-1<n) g[d-1]=mod-1;
    }
    g[0]=1;
    g=log(~g);
    for(int i=0;i<n;++i) g[i]=mul(g[i],n);
    g=exp(g);
    int ans=mul(g[n-1],inv[n]);
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/autoint/p/12183077.html