将
a
,
b
a,b
a,b 的路径拿出来,考虑方案数就是拓扑序数,即
n
!
∏
1
s
i
z
e
i
n!\prod \frac{1}{size_i}
n!∏sizei1 现在有两个点,考虑这个过程是左右左右选 那么枚举断边,贡献就是
∏
i
=
1
u
1
S
u
−
S
i
−
1
∗
∏
i
=
u
+
1
k
1
S
i
−
S
u
\prod_{i=1}^u\frac{1}{S_u-S_{i-1}}*\prod_{i=u+1}^k\frac{1}{S_{i}-S_{u}}
i=1∏uSu−Si−11∗i=u+1∏kSi−Su1 其中
S
S
S 为
s
i
z
e
size
size 的前缀和,断边的两个子树是无序拼接 考虑把
−
1
-1
−1 的系数提出来,即求
∏
i
=
1
k
x
−
S
i
x
−
S
u
∣
x
=
S
u
\frac{\prod_{i=1}^kx-S_i}{x-S_u}\Big|_{x=S_u}
x−Su∏i=1kx−Si∣∣∣x=Su 洛必达法则,求导后多点求值,枚举边会算重,枚举点没法做,但枚举边除
a
,
b
a,b
a,b 每个点都被算了两次,加上
a
,
b
a,b
a,b 的贡献除以 2 即可
#include<bits/stdc++.h>
#define cs const
#define pb push_back
#define poly vector<int>
using namespace std;
namespace IO{
cs int Rlen=1<<22|1;
inline char gc(){
static char buf[Rlen], *p1, *p2;(p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin));
return p1==p2?EOF:*p1++;}int read(){
int x=0; char c=gc(); bool f=false;while(!isdigit(c)) f=c=='-', c=gc();while(isdigit(c)) x=(((x<<2)+x)<<1)+(c^48), c=gc();
return f?-x:x;}} using namespace IO;
cs int Mod = 998244353;
int add(int a, int b){ return a + b >= Mod ? a + b - Mod: a + b;}int dec(int a, int b){ return a - b < 0 ? a - b + Mod: a - b;}int mul(int a, int b){ return 1ll * a * b % Mod;}void Add(int &a, int b){ a = add(a,b);}void Dec(int &a, int b){ a = dec(a,b);}void Mul(int &a, int b){ a = mul(a,b);}int ksm(int a, int b){ int as=1;for(;b;b>>=1,Mul(a,a))if(b&1)Mul(as,a); return as;}void output(poly a){for(int x: a) cout << x << " ";puts("");}
cs int N = 1 << 19 | 1;
int n, a, b, coe[N];
int fc[N], ifc[N], iv[N];
void fc_init(int n){
fc[0]=fc[1]=ifc[0]=ifc[1]=1;for(int i=2; i<=n; i++) fc[i]=mul(fc[i-1],i);for(int i=2; i<=n; i++) ifc[i]=mul(ifc[i-1],iv[i]);}
vector<int> G[N];
int sz[N], fa[N], szc[N];
void dfs(int u, int f){
sz[u] = szc[u] = 1;
for(int v : G[u]) if(v ^ f){
fa[v] = u;dfs(v,u); sz[u] += sz[v];Mul(szc[u], szc[v]);}Mul(szc[u], iv[sz[u]]);}
cs int K = 19;
poly w[K+1];
void NTT_init(){for(int i=1; i<=K; i++) w[i].resize(1<<(i-1));
int wn=ksm(3,(Mod-1)/(1<<K)); w[K][0]=1;for(int i=1; i<(1<<(K-1)); i++) w[K][i]=mul(w[K][i-1],wn);for(int i=K-1;i;i--)for(int j=0; j<(1<<(i-1)); j++) w[i][j]=w[i+1][j<<1];
iv[0]=iv[1]=1;for(int i=2; i<=(1<<K); i++) iv[i]=mul(Mod-Mod/i,iv[Mod%i]);}
int up, bit; poly rev;
void init(int deg){
up=1; bit=0;while(up<deg) up<<=1,++bit; rev.resize(up);for(int i=0; i<up; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));}void NTT(poly &a, int typ=1){for(int i=0; i<up; i++)if(i<rev[i])swap(a[i],a[rev[i]]);for(int i=1,l=1; i<up; i<<=1,++l)for(int j=0; j<up; j+=(i<<1))for(int k=0; k<i; k++){
int x=a[k+j], y=mul(w[l][k],a[k+j+i]);
a[k+j]=add(x,y); a[k+j+i]=dec(x,y);}if(typ==-1){reverse(a.begin()+1,a.end());for(int i=0; i<up; i++)Mul(a[i],iv[up]);}}poly operator * (poly a, poly b){
int deg=a.size()+b.size()-1;
if(a.size()<=16||b.size()<=16){
poly c(deg,0);for(int i=0; i<(int)a.size(); i++)for(int j=0; j<(int)b.size(); j++)Add(c[i+j],mul(a[i],b[j])); return c;}init(deg); a.resize(up); b.resize(up);NTT(a);NTT(b);for(int i=0; i<up; i++)Mul(a[i],b[i]);NTT(a,-1);
a.resize(deg); return a;}poly inv(poly a, int deg){
poly b(1,ksm(a[0],Mod-2)),c;for(int lim=2;(lim>>1)<deg; lim<<=1){
c=a; c.resize(lim);init(lim<<1);
c.resize(up); b.resize(up);NTT(c);NTT(b);for(int i=0; i<up; i++)Mul(b[i],dec(2,mul(b[i],c[i])));NTT(b,-1); b.resize(lim);} b.resize(deg); return b;}poly integ(poly a){
a.pb(0);for(int i=a.size()-1; i>=1; i--) a[i]=mul(a[i-1],iv[i]);
a[0]=0; return a;}poly deriv(poly a){for(int i=0; i+1<(int)a.size(); i++) a[i]=mul(a[i+1],i+1);
a.pop_back(); return a;}void operator -= (poly &a, cs poly &b){if(a.size() < b.size()) a.resize(b.size());for(int i=0; i<(int)b.size(); i++)Dec(a[i],b[i]);}poly operator / (poly a, poly b){
int deg = a.size()-b.size()+1;reverse(a.begin(),a.end()), a.resize(deg);reverse(b.begin(),b.end()), a = a * inv(b,deg);
a.resize(deg);reverse(a.begin(),a.end()); return a;}poly operator % (poly a, poly b){if(a.size()<b.size()) return a;
a -= b * (a / b); a.resize(b.size()-1); return a;}
poly f[N];
void work(int x, int l, int r, int *S){if(l==r){ f[x].pb(dec(0,S[l])); f[x].pb(1); return;}
int mid=(l+r)>>1;work(x<<1,l,mid,S);work(x<<1|1,mid+1,r,S);
f[x] = f[x<<1] * f[x<<1|1];}void solve(int x, int l, int r, poly F){if(l==r) return coe[l]=F[0],void();
int mid=(l+r)>>1;solve(x<<1,l,mid,F%f[x<<1]);solve(x<<1|1,mid+1,r,F%f[x<<1|1]);}int main(){
#ifdef FSYolanda
freopen("tommy.in","r",stdin);
#endif
// freopen("tp.in","r",stdin);
n=read(), a=read(), b=read();
NTT_init();
fc_init(n);for(int i=1,x,y; i<n; i++)
x=read(), y=read(), G[x].pb(y), G[y].pb(x);dfs(a,0);
int Sm = fc[n];
static int S[N]; int c = 0;for(int x=b,l=0;x;l=x,x=fa[x]){
// cout<<x<<" "<<sz[x]-sz[l]<<endl;
S[++c] = sz[x] - sz[l];for(int v: G[x])if(v!=fa[x] && v!=l)Mul(Sm, szc[v]);}
// for(int i=1; i<=c; i++) cout<<S[i]<<" "; cout<<endl;for(int i=1; i<=c; i++) S[i]+=S[i-1];work(1,0,c,S);
// output(f[1]);
poly F = deriv(f[1]);
// output(F);solve(1,0,c,F);
int as = 0;for(int i=1; i<c; i++){if((c-i)&1) coe[i]=dec(0,coe[i]);
// cout<<coe[i]<<endl;Add(as, mul(ksm(coe[i],Mod-2),Sm));}
int coef = Sm;for(int i=1; i<=c; i++)Mul(coef,iv[S[i]]);Add(as,coef);
coef = Sm;for(int i=0; i<c; i++)Mul(coef,iv[S[c]-S[i]]);Add(as,coef);
cout<<mul(as,iv[2]); return 0;}