LOJ2526 "HAOI2018" apple tree

Description

Topic Link

Feel that Italy has been very clear, direct link stamp on the line

Solution

Consider in a \ (n-\) tree nodes connected to the new node calculation, but if the shape of a tree found that variable path length can not calculated, all the path length of the connection and do not have any law

Taking into account a tree, there are two specific points: the leaves and roots, since then a new node does not work, then we consider the root to a large binary split into two smaller binary tree (can be empty)

Tried \ (3 \) states design method, the finally selected one of the most readily occur trying, i.e. set \ (dp_i \) represents \ (I \) long point the sum of all possible program paths

But try to find such a place a little bit of trouble, but also consider the contribution is generated between the two separated binary tree, that we have to calculate a \ (f_ {i, j} \) array, represents a size \ (I \) of the binary tree of size \ (J \) contribution generated binary tree, when the accumulated even more plus \ (f_ {i, j} (ji-1)! + f_ {ji-1 , j} i! \)

In this case, we might as well let \ (dp_i \) represents \ (i \) sub binary tree nodes of the global ( \ (the n-\) contribution binary tree nodes) generated, you can get
\ [dp_i = \ sum \ limits_ {j = 0} ^ {i-1} \ dbinom {i-1} {j} (dp_j (ij-1)! + dp_ {ij-1} j! + (ij-1)! j! (j \ times (nj) +
(ij-1) \ times (n-i + j + 1))) \] how to understand this equation?

First, for a binary tree to determine, after generating the root we can complete its turn generate two nodes within the subtree, then there will be a total of \ (\ binom {i-1 } {j} \) kinds of programs (as two sub generating a binary sequence has been secured in)

Secondly, we know that \ (dp_i \) indicates that all \ (I \) long binary path nodes sum, if used \ (C_J \) represents the \ (J \) Species \ (I \) points binary tree path total length, then \ (dp_i \) is equivalent to the result of the addition principle obtained, i.e.
\ [dp_i = \ sum \ limits_
{j = 1} ^ {i!} c_j \] where \ (I! \) is \ (I \) nodes may generate a total of \ (I! \) species binary tree (there may be duplicate form)

Now suppose that we have generated in a certain order within a left subtree \ (j \) points, there is within the right subtree \ (ij-1 \) binary points

Then the contribution of their respective internal global generation is \ (dp_j (ij of-. 1)! + Dp_ {ij of-. 1} J! \) , Factorial intended multiplied is in the case of a subtree finalized, and the other one sub tree seed tree match will factorial

Now we are still root even without considering that the two sides of the two sub-tree, is easy to find their contribution to global is \ (j \ times (nj) + (ij-1) \ times (n-i + j + 1) \) , have multiplied \ ((ij-1)! J! \) , because there are so many trees two sub-matching scheme, in each matching program, we have to add to this contribution

This question then finished it, the complexity of the \ (O (n ^ 2) \)

In fact, this question is quite abstract, calls for careful thought

Harvest is probably

  • For all out of the tree generation according to certain rules (and possibly also FIG like), some of their values ​​to be calculated, this problem can be considered in the original tree plus point, or the original root from the tree split into two smaller tree (the latter may be more suitable for some sense)
  • If an element of the contribution of local produce bad count (or counted too much trouble), and overall contribution to the final requirement is to push up the local contribution, it can contribute directly to consider this element of the global produce
  • Some of the more abstract questions when thinking must sort out ideas

code show as below:

#include<cstdio>
#include<iostream>
using namespace std;
const int N=2e3+10;
int n,mod,c[N][N],fac[N],dp[N];
inline int MOD(int x){x-=x>=mod? mod:0;return x;}
inline void Add(int &x,int y){x+=y;x-=x>=mod? mod:0;}
inline int Minus(int x){x+=x<0? mod:0;return x;}
int main(){
    scanf("%d%d",&n,&mod);
    for(register int i=0;i<=n;i++){
        c[i][0]=1;
        for(register int j=1;j<=i;j++)
            c[i][j]=MOD(c[i-1][j]+c[i-1][j-1]);
    }
    fac[0]=1;for(register int i=1;i<=n;i++)fac[i]=1ll*fac[i-1]*i%mod;
    for(register int i=1;i<=n;i++)
        for(register int j=0;j<i;j++)
            Add(dp[i],1ll*c[i-1][j]*MOD(MOD(1ll*dp[j]*fac[i-j-1]%mod+1ll*dp[i-j-1]*fac[j]%mod)+1ll*fac[j]*fac[i-j-1]%mod*MOD(1ll*j*(n-j)%mod+1ll*(i-j-1)*(n-i+j+1)%mod)%mod)%mod);
    printf("%d\n",dp[n]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/ForwardFuture/p/11548763.html