p5405 [CTS2019] krypton gold hand tour

Subject to the effect

The meaning of problems bullshit

Look Westerner language than to look at this problem face strong

 analysis

We assume that this tree is a tree within

Then we can easily get dp [x] [i] represents the x tree ideas and expectations for the i

Just transfer the desired size and enumerate the current sub-tree to the desired size

However, due to the direction of the edge is not necessarily

So there is the reverse side of this tree

We can inclusion and exclusion sides have i not lawful

So for a reverse side of the legal relationship either x plus point, the sub-tree isolated contribution

Either this side regarded as illegal

In this case we can directly contribute lose

Because we already know that this contribution is from 0 to inclusion and exclusion of case i

And this is equivalent to minus * -1

You can complete inclusion-exclusion

Complexity of O (n ^ 2)

Code

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
const int mod = 998244353;
int dp[1100][3300],n,m,inv[3300],res[3300],siz[1100];
vector<pair<int,int> >v[1100];
inline int pw(int x,int p){
    int ans=1;
    while(p){
      if(p&1)ans=1ll*ans*x%mod;
      x=1ll*x*x%mod;
      p>>=1;
    }
    return ans;
}
inline void dfs(int x,int fa){
    siz[x]=1;
    for(int i=0;i<v[x].size();i++)
      if(v[x][i].fi!=fa){
          int y=v[x][i].fi,z=v[x][i].se;
          DFS (y, x); 
          for ( int j = 0 ; j <= 3 * siz [x]; j ++ )
             for ( int k = 0 ; k <= 3 * siz [y]; k ++ ) {
                 int sum = 1ll * dp [x] [j ] * dp [y] [k]% mod;
                if (z) res [j + k] = (res [j + k] + sum)% mod;
                  else res [j + k] = (res [j + k] -sum + mod)% mod, res [j] = (res [j] + sum)% mod; 
          } 
          Siz [x] + = siz [y];
          for ( int j = 0 ; j <= 3 * siz [x]; j ++) dp [x] [j] = res [j], res [j] =0;
      }
    for(int i=0;i<=3*siz[x];i++)dp[x][i]=1ll*dp[x][i]*inv[i]%mod;
}
int main(){
    int i,j,k,ans=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++){
      int x,y,z,iv;
      scanf("%d%d%d",&x,&y,&z);
      iv=pw(x+y+z,mod-2);
      dp[i][1]=1ll*x*iv%mod;
      dp[i][2]=2ll*y*iv%mod;
      dp[i][3]=3ll*z*iv%mod;
    }
    for(i=1;i<n;i++){
      int x,y;
      scanf("%d%d",&x,&y);
      v[x].pb(mp(y,1));
      v[y].pb(mp(x,0));
    }
    inv[0]=inv[1]=1;
    for(i=2;i<=3*n;i++)inv[i]=pw(i,mod-2);
    dfs(1,0);
    for(i=0;i<=3*n;i++)ans=(ans+dp[1][i])%mod;
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/yzxverygood/p/11519598.html