提交时间:2024-10-20 18:40:10
运行 ID: 33742
#include<bits/stdc++.h> using namespace std; #define int long long #define pb push_back const int N=5010,M=998244353; //f[i][0/1]:以i为根的子树,是否联通(联通是指i点这个大点所包含的两个小点(i,i+n)是否联通) //这样设计是为了保证不会有重复的联通,即不再是生成树 int n,pw[N],f[N][3]; //mch:i点是否已经有相应的x+i号点来匹配 bool mch[N],vis[N]; vector<int>e[N<<1]; void dp(int u){ if(vis[u])return;vis[u]=1; f[u][0]=1;f[u][1]=0; int cnt=0; for(auto v:e[u]){ if(vis[v])continue; if(mch[v]){ dp(v); f[u][1]=((f[u][0]*f[v][1])%M+(f[u][1]*f[v][0])%M+(f[u][1]*f[v][1]*2)%M)%M; f[u][0]=((f[u][0]*f[v][0])%M+(f[u][0]*f[v][1]*2)%M); } else cnt++; } if(cnt>0){ f[u][1]=(f[u][0]*((cnt*pw[cnt-1])%M)%M+f[u][1]*pw[cnt]%M)%M; f[u][0]=f[u][0]*pw[cnt]%M; } } signed main(){ pw[0]=1; for(int i=1;i<=5005;i++){pw[i]=pw[i-1]*2%M;} cin>>n; int u,v; for(int i=1;i<=n-1;i++){ cin>>u>>v; e[u].pb(v);e[v].pb(u); } int x; for(int i=1;i<=n-1;i++){ memset(vis,0,sizeof(vis)); cin>>x;mch[x]=1; int res=1; for(int j=1;j<=n;j++){ if(mch[j]&&!vis[j]){ dp(j); res*=f[j][1];res%=M; } } cout<<res<<endl; } return 0; }