首先分析下问题,很容易得出,如果设
T
0
T_0
T0 表示一个
n
n
n 个点的森林,边集为两棵树
T
1
T_1
T1 和
T
2
T_2
T2 的边交集,且
T
0
T_0
T0 包含
c
n
t
cnt
cnt 个连通块,则答案为
y
c
n
t
y^{cnt}
ycnt
利用 map 等很多技巧都可以求两棵树的边交集
O
(
n
log
n
)
O(n\log n)
O(nlogn)
Task 2 :
o
p
=
1
op=1
op=1
前置知识:已经确定一些边的生成树计数
这个问题大致为:有
m
m
m 个连通块,第
i
i
i 个连通块包含
a
i
a_i
ai 个点,
n
=
∑
i
=
1
m
a
i
n=\sum_{i=1}^ma_i
n=∑i=1mai
求用
m
−
1
m-1
m−1 条边连接
m
m
m 个连通块的方案数
考虑一种对树进行计数的工具 prufer 序列
先考虑,如果对于所有的
i
i
i 都有
a
i
=
1
a_i=1
ai=1 ,那么长度为
m
−
2
m-2
m−2 的 prufer 序列每个元素都可以取
m
m
m 个点中的任一个,方案数
m
m
−
2
m^{m-2}
mm−2
此外, prufer 序列的另一个性质:度数为
d
d
d 的点在序列中出现
d
−
1
d-1
d−1 次
回到
a
i
a_i
ai 不一定等于
1
1
1 的情况,设第
i
i
i 的点的度数为
d
i
d_i
di
那么第
i
i
i 个连通块会让方案数额外乘上
a
i
d
i
a_i^{d_i}
aidi
我们可以把过程看成如下
初始时设
r
e
s
=
∏
i
=
1
m
a
i
res=\prod_{i=1}^ma_i
res=∏i=1mai
然后考虑 prufer 序列的第
i
i
i 个元素
p
i
p_i
pi
如果
p
i
p_i
pi 取
u
u
u ,那么会为方案数乘上
a
u
a_u
au ,而
p
i
p_i
pi 可以取
m
m
m 个连通块中的任一,故将
r
e
s
res
res 乘上
n
n
n
注意到处理 prufer 的过程中,第
i
i
i 个连通块贡献了
d
i
−
1
d_i-1
di−1 次
a
i
a_i
ai,再乘上初始的
∏
i
=
1
m
a
i
\prod_{i=1}^ma_i
∏i=1mai 恰好是贡献
d
i
d_i
di 次
所以方案数为
r
e
s
=
n
m
−
2
∏
i
=
1
m
a
i
res=n^{m-2}\prod_{i=1}^ma_i
res=nm−2i=1∏mai
回到问题
我们知道,对于森林,有:边数
+
+
+ 连通块个数
=
=
= 点数
设
C
(
S
)
C(S)
C(S) 表示树
T
2
T_2
T2 有多少种取法使得
T
1
T_1
T1 与
T
2
T_2
T2 的边交集恰好为
S
S
S
那么答案显然为
∑
S
C
(
S
)
×
y
n
−
∣
S
∣
\sum_SC(S)\times y^{n-|S|}
S∑C(S)×yn−∣S∣
考虑利用容斥化一下
C
(
S
)
C(S)
C(S)
设
D
(
S
)
D(S)
D(S) 表示树
T
2
T_2
T2 有多少种取法使得边集
S
S
S 是
T
1
T_1
T1 与
T
2
T_2
T2 的边交集的子集
那么
D
(
S
)
D(S)
D(S) 显然比
C
(
S
)
C(S)
C(S) 容易直接求。这就相当于
T
1
T_1
T1 和
T
2
T_2
T2 都必须包含边集
S
S
S
于是
D
(
S
)
D(S)
D(S) 就相当于有
∣
S
∣
|S|
∣S∣ 条边已经确定的情况下,在剩下的边中选
n
−
1
−
∣
S
∣
n-1-|S|
n−1−∣S∣ 条,连通所有点的方案数,可以用上面介绍的 prufer 序列计数求得
于是求
C
(
S
)
C(S)
C(S) 我们可以容斥
C
(
S
)
=
∑
S
⊂
T
(
−
1
)
∣
T
∣
−
∣
S
∣
D
(
T
)
C(S)=\sum_{S\subset T}(-1)^{|T|-|S|}D(T)
C(S)=S⊂T∑(−1)∣T∣−∣S∣D(T)
代入答案的式子
a
n
s
w
e
r
=
y
n
∑
S
(
y
−
1
)
∣
S
∣
C
(
S
)
answer=y^n\sum_S(y^{-1})^{|S|}C(S)
answer=ynS∑(y−1)∣S∣C(S)
=
y
n
∑
S
(
y
−
1
)
∣
S
∣
∑
S
⊂
T
(
−
1
)
∣
T
∣
−
∣
S
∣
D
(
T
)
=y^n\sum_S(y^{-1})^{|S|}\sum_{S\subset T}(-1)^{|T|-|S|}D(T)
=ynS∑(y−1)∣S∣S⊂T∑(−1)∣T∣−∣S∣D(T)
把
T
T
T 集合提到外层枚举
=
y
n
∑
T
D
(
T
)
∑
S
⊂
T
(
y
−
1
)
∣
S
∣
(
−
1
)
∣
T
∣
−
∣
S
∣
=y^n\sum_TD(T)\sum_{S\subset T}(y^{-1})^{|S|}(-1)^{|T|-|S|}
=ynT∑D(T)S⊂T∑(y−1)∣S∣(−1)∣T∣−∣S∣
发现在枚举
S
⊂
T
S\subset T
S⊂T 时,
∣
S
∣
|S|
∣S∣ 相同的集合
S
S
S 本质上没有区别
=
y
n
∑
T
D
(
T
)
∑
i
=
0
∣
T
∣
(
∣
T
∣
i
)
(
y
−
1
)
i
(
−
1
)
∣
T
∣
−
i
=y^n\sum_TD(T)\sum_{i=0}^{|T|}\binom{|T|}i(y^{-1})^i(-1)^{|T|-i}
=ynT∑D(T)i=0∑∣T∣(i∣T∣)(y−1)i(−1)∣T∣−i
由二项式定理得
=
y
n
∑
T
D
(
T
)
(
y
−
1
−
1
)
∣
T
∣
=y^n\sum_TD(T)(y^{-1}-1)^{|T|}
=ynT∑D(T)(y−1−1)∣T∣
注意这里的
T
T
T 只能取树
T
1
T_1
T1 的边子集
发现当
y
=
1
y=1
y=1 时会对我们的处理造成不便,直接特判掉:
y
=
1
y=1
y=1 时答案为
n
n
−
2
n^{n-2}
nn−2
然后继续转化上式,设
R
(
S
)
R(S)
R(S) 表示
n
n
n 个点,加入树
T
1
T_1
T1 中除边集
S
S
S 之外的所有边之后,每个连通块大小之积,根据上面介绍的 prufer 序列计数,可以得到
=
y
n
∑
S
n
∣
S
∣
−
1
R
(
S
)
(
y
−
1
−
1
)
n
−
(
∣
S
∣
+
1
)
=y^n\sum_Sn^{|S|-1}R(S)(y^{-1}-1)^{n-(|S|+1)}
=ynS∑n∣S∣−1R(S)(y−1−1)n−(∣S∣+1)
=
(
y
(
y
−
1
−
1
)
)
n
n
2
∑
S
R
(
S
)
(
n
(
y
−
1
−
1
)
−
1
)
∣
S
∣
+
1
=\frac{(y(y^{-1}-1))^n}{n^2}\sum_SR(S)(n(y^{-1}-1)^{-1})^{|S|+1}
=n2(y(y−1−1))nS∑R(S)(n(y−1−1)−1)∣S∣+1
(
y
(
y
−
1
−
1
)
)
n
n
2
\frac{(y(y^{-1}-1))^n}{n^2}
n2(y(y−1−1))n 这一部分可以在算好后面的部分之后再去乘上。我们设
Y
=
n
(
y
−
1
−
1
)
−
1
Y=n(y^{-1}-1)^{-1}
Y=n(y−1−1)−1 ,那么
∑
S
R
(
S
)
Y
∣
S
∣
+
1
\sum_SR(S)Y^{|S|+1}
∑SR(S)Y∣S∣+1 就相当于把树
T
1
T_1
T1 分成几个连通块,分成
i
i
i 个连通块的贡献为
Y
i
Y^i
Yi 乘上所有连通块的大小之积
这显然可以用树形 DP 解决
发现由于需要考虑所有连通块的大小之积,所以这个 DP 是
O
(
n
2
)
O(n^2)
O(n2) 的
我们不妨寻找一个
R
(
S
)
Y
∣
S
∣
+
1
R(S)Y^{|S|+1}
R(S)Y∣S∣+1 的组合意义
这相当于在
∣
S
∣
+
1
|S|+1
∣S∣+1 个连通块中,每个连通块内各选一点,选一个点会乘上
Y
Y
Y 的贡献
于是
∑
S
R
(
S
)
Y
∣
S
∣
+
1
\sum_SR(S)Y^{|S|+1}
∑SR(S)Y∣S∣+1 就相当于选出一些点,若选出了
i
i
i 个点,那么贡献为
Y
i
Y^i
Yi 乘上选出
i
−
1
i-1
i−1 条边切掉使得这
i
i
i 个点两两不连通的方案数
于是我们可以开始 DP 了
f
[
u
]
f[u]
f[u] 表示
u
u
u 的子树内选出一些点,使得这些点归属不同的连通块
g
[
u
]
g[u]
g[u] 表示
u
u
u 的子树内选出一些点(不能选
u
u
u ),使得
u
u
u 归属一个连通块,选出的点各自位于一个连通块
如果
u
u
u 的子树只有一个点则
f
[
u
]
=
Y
f[u]=Y
f[u]=Y ,
g
[
u
]
=
1
g[u]=1
g[u]=1
使用背包合并的方式转移,如果
u
u
u 处理到子树
v
v
v 之前的 DP 数组为
f
′
f'
f′ 和
g
′
g'
g′ ,则
f
[
u
]
=
f
′
[
u
]
×
f
[
v
]
+
g
′
[
u
]
×
f
[
v
]
+
f
′
[
u
]
×
g
[
v
]
f[u]=f'[u]\times f[v]+g'[u]\times f[v]+f'[u]\times g[v]
f[u]=f′[u]×f[v]+g′[u]×f[v]+f′[u]×g[v]
g
[
u
]
=
g
′
[
u
]
×
f
[
v
]
+
g
′
[
u
]
×
g
[
v
]
g[u]=g'[u]\times f[v]+g'[u]\times g[v]
g[u]=g′[u]×f[v]+g′[u]×g[v]
即转移时分
(
u
,
v
)
(u,v)
(u,v) 切掉与不切掉进行讨论
于是答案为
(
y
(
y
−
1
−
1
)
)
n
n
2
f
[
R
o
o
t
]
\frac{(y(y^{-1}-1))^n}{n^2}f[Root]
n2(y(y−1−1))nf[Root]
O
(
n
)
O(n)
O(n)
Task 3 :
o
p
=
2
op=2
op=2
前置知识:指数生成函数与多项式 EXP
定义组合对象
A
A
A 的指数生成函数
F
(
x
)
F(x)
F(x) 为
F
(
x
)
=
∑
i
≥
0
A
i
i
!
F(x)=\sum_{i\ge 0}\frac{A_i}{i!}
F(x)=i≥0∑i!Ai
可以得出,如果组合对象
A
A
A 和
B
B
B 的指数生成函数分别为
F
(
x
)
F(x)
F(x) 和
G
(
x
)
G(x)
G(x) ,那么将这两个组合对象进行带标号拼接得到
C
C
C ,则
C
C
C 的指数生成函数
H
(
x
)
H(x)
H(x) 有
[
x
n
]
H
(
x
)
=
C
n
n
!
=
∑
i
+
j
=
n
(
n
i
)
A
i
B
j
(
n
!
)
−
1
[x^n]H(x)=\frac{C_n}{n!}=\sum_{i+j=n}\binom niA_iB_j(n!)^{-1}
[xn]H(x)=n!Cn=i+j=n∑(in)AiBj(n!)−1
=
∑
i
+
j
=
n
[
x
i
]
F
(
x
)
[
x
j
]
G
(
x
)
=\sum_{i+j=n}[x^i]F(x)[x^j]G(x)
=i+j=n∑[xi]F(x)[xj]G(x)
即
H
(
x
)
=
F
(
x
)
G
(
x
)
H(x)=F(x)G(x)
H(x)=F(x)G(x)
然后引入多项式 EXP
设组合对象
A
A
A 的指数生成函数
F
(
x
)
F(x)
F(x) (
A
0
=
0
A_0=0
A0=0 ),有
e
F
(
x
)
=
∑
i
≥
0
F
i
(
x
)
i
!
e^{F(x)}=\sum_{i\ge 0}\frac{F^i(x)}{i!}
eF(x)=i≥0∑i!Fi(x)
显然
F
i
(
x
)
F^i(x)
Fi(x) 表示
i
i
i 个组合对象
A
A
A 带标号拼接
F
i
(
x
)
i
!
\frac{F^i(x)}{i!}
i!Fi(x) 表示
i
i
i 个组合对象
A
A
A 不考虑彼此顺序的拼接
于是
e
F
(
x
)
e^{F(x)}
eF(x) 表示一些组合对象
A
A
A 进行不考虑彼此顺序的拼接
以上概念可能有些含糊,所以我们引入一个例子
如,无向简单图(不含重边和自环)是由若干无向简单连通图构成的
连通块之间没有顺序
所以若无向简单图个数的指数生成函数为
G
(
x
)
G(x)
G(x) ,无向简单连通图个数的指数生成函数为
F
(
x
)
F(x)
F(x) ,则
G
(
x
)
=
e
F
(
x
)
G(x)=e^{F(x)}
G(x)=eF(x)
显然
G
(
x
)
G(x)
G(x) 是个形式幂级数,我们如何求得
G
(
x
)
 
m
o
d
 
x
n
G(x)\bmod x^n
G(x)modxn 呢?
由牛顿迭代得
G
k
+
1
(
x
)
=
G
k
(
x
)
(
1
−
ln
G
k
(
x
)
+
F
(
x
)
)
G_{k+1}(x)=G_k(x)(1-\ln G_k(x)+F(x))
Gk+1(x)=Gk(x)(1−lnGk(x)+F(x))
其中
G
k
(
x
)
=
G
(
x
)
 
m
o
d
 
x
2
k
,
G
0
(
x
)
=
1
G_k(x)=G(x)\bmod x^{2^k},G_0(x)=1
Gk(x)=G(x)modx2k,G0(x)=1
将
k
k
k 从
1
1
1 迭代到
≥
n
\ge n
≥n 为止即可。复杂度
O
(
n
log
n
)
O(n\log n)
O(nlogn)
回到问题
特判掉
y
=
1
y=1
y=1 时答案为
n
2
(
n
−
2
)
n^{2(n-2)}
n2(n−2)
前面的容斥推导基本一样,同样地
a
n
s
w
e
r
=
y
n
∑
T
D
(
T
)
(
y
−
1
−
1
)
∣
T
∣
answer=y^n\sum_TD(T)(y^{-1}-1)^{|T|}
answer=ynT∑D(T)(y−1−1)∣T∣
注意,这时候
D
(
T
)
D(T)
D(T) 表示钦定边集
T
T
T 时
n
n
n 个点生成树个数的平方(因为要确定两棵树),这里的
T
T
T 可以取任意不成环的边集
易得
D
(
T
)
D(T)
D(T) 等于
n
n
n 的
2
(
n
−
∣
T
∣
−
2
)
2(n-|T|-2)
2(n−∣T∣−2) 次幂,乘上所有连通块大小之积的平方,但如果我们枚举的是连通块分属情况而不是边集
T
T
T ,我们还需要考虑每个连通块长什么样
我们尝试把枚举
T
T
T 改成枚举边集
T
T
T 的连通块分属情况,则
a
n
s
w
e
r
=
(
y
(
y
−
1
−
1
)
)
n
n
4
∑
T
s
(
n
2
(
y
−
1
−
1
)
−
1
)
∣
T
s
∣
∏
i
=
1
∣
T
s
∣
T
s
i
T
s
i
answer=\frac{(y(y^{-1}-1))^n}{n^4}\sum_{Ts}(n^2(y^{-1}-1)^{-1})^{|Ts|}\prod_{i=1}^{|Ts|}Ts_i^{Ts_i}
answer=n4(y(y−1−1))nTs∑(n2(y−1−1)−1)∣Ts∣i=1∏∣Ts∣TsiTsi
其中
T
s
Ts
Ts 为一种连通块划分,
∣
T
s
∣
|Ts|
∣Ts∣ 为连通块个数,
T
s
i
Ts_i
Tsi 为第
i
i
i 个连通块大小,
∏
i
=
1
∣
T
s
∣
T
s
i
T
s
i
\prod_{i=1}^{|Ts|}Ts_i^{Ts_i}
∏i=1∣Ts∣TsiTsi 即为对划分方案
T
s
Ts
Ts 来说,每个连通块的生成树个数之积,再乘上每个连通块大小之积的平方
就
∑
\sum
∑ 后面的东西进行考虑,如果只有一个大小为
i
i
i 的连通块,设
Y
=
n
2
(
y
−
1
−
1
)
−
1
Y=n^2(y^{-1}-1)^{-1}
Y=n2(y−1−1)−1
f
[
i
]
=
i
i
×
Y
f[i]=i^i\times Y
f[i]=ii×Y
设
F
(
x
)
F(x)
F(x) 为
f
[
i
]
f[i]
f[i] 的指数生成函数,那么发现
∑
T
s
(
n
2
(
y
−
1
−
1
)
−
1
)
∣
T
s
∣
∏
i
=
1
∣
T
s
∣
T
s
i
T
s
i
\sum_{Ts}(n^2(y^{-1}-1)^{-1})^{|Ts|}\prod_{i=1}^{|Ts|}Ts_i^{Ts_i}
∑Ts(n2(y−1−1)−1)∣Ts∣∏i=1∣Ts∣TsiTsi 其实就等于
n
!
[
x
n
]
e
F
(
x
)
n![x^n]e^{F(x)}
n![xn]eF(x) ,直接套用多项式 exp 的板子即可
O
(
n
log
n
)
O(n\log n)
O(nlogn)
Code
#include<bits/stdc++.h>// 20030830inlineintread(){int res =0;bool bo =0;char c;while(((c =getchar())<'0'|| c >'9')&& c !='-');if(c =='-') bo =1;else res = c -48;while((c =getchar())>='0'&& c <='9')
res =(res <<3)+(res <<1)+(c -48);return bo ?~res +1: res;}template<classT>inlinevoidSwap(T &a, T &b){T t = a; a = b; b = t;}constint N =1e5+5, M = N <<1, L = N *7, ZZQ =998244353,
INV2 =499122177, INV4 =748683265;int n, y, op;intqpow(int a,int b){int res =1;while(b){if(b &1) res =1ll* res * a % ZZQ;
a =1ll* a * a % ZZQ;
b >>=1;}return res;}namespace solve0
{int fa[N], ans;
std::map<int,int> app[N];intcx(int x){if(fa[x]!= x) fa[x]=cx(fa[x]);return fa[x];}voidzm(int x,int y){int ix =cx(x), iy =cx(y);if(ix != iy) fa[iy]= ix;}voidwork(){int u, v;for(int i =1; i <= n; i++) fa[i]= i;for(int i =1; i < n; i++)
u =read(), v =read(), app[u][v]= app[v][u]=1;for(int i =1; i < n; i++){
u =read(); v =read();if(app[u][v])zm(u, v);}for(int i =1; i <= n; i++)if(cx(i)== i) ans++;printf("%d\n",qpow(y, ans));}};namespace solve1
{int ecnt, nxt[M], adj[N], go[M], f[N], g[N];voidadd_edge(int u,int v){
nxt[++ecnt]= adj[u]; adj[u]= ecnt; go[ecnt]= v;
nxt[++ecnt]= adj[v]; adj[v]= ecnt; go[ecnt]= u;}voiddfs(int u,int fu){
f[u]= y; g[u]=1;for(int e = adj[u], v; e; e = nxt[e]){if((v = go[e])== fu)continue;dfs(v, u);int tf =(1ll* f[u]* f[v]+1ll* g[u]* f[v]+1ll* f[u]* g[v])% ZZQ,
tg =(1ll* g[u]* f[v]+1ll* g[u]* g[v])% ZZQ;
f[u]= tf; g[u]= tg;}}voidwork(){int u, v;for(int i =1; i < n; i++)
u =read(), v =read(),add_edge(u, v);if(y ==1)return(void)printf("%d\n",qpow(n, n -2));int st =1ll* y *(qpow(y, ZZQ -2)-1)% ZZQ;
y =1ll*qpow(qpow(y, ZZQ -2)-1, ZZQ -2)* n % ZZQ;dfs(1,0);printf("%d\n",1ll*qpow(st, n)* f[1]% ZZQ
*qpow(1ll* n * n % ZZQ, ZZQ -2)% ZZQ);}};namespace solve2
{int fac[L], inv[L], invf[L], f[L], yp[L], rev[L], ta[L], tb[L],
tmpf[L], tmpg[L], da[L], inva[L], tf[L], tg[L], tln[L], ans[L];voidFFT(int n,int*a,int op){for(int i =0; i < n; i++)if(i < rev[i])Swap(a[i], a[rev[i]]);
yp[n]=qpow(3,(ZZQ -1)/ n *((n + op)% n));for(int i = n >>1; i; i >>=1)
yp[i]=1ll* yp[i <<1]* yp[i <<1]% ZZQ;for(int k =1; k < n; k <<=1){int x = yp[k <<1];for(int i =0; i < n; i += k <<1){int w =1;for(int j =0; j < k; j++){int u = a[i + j], v =1ll* w * a[i + j + k]% ZZQ;
a[i + j]=(u + v)% ZZQ;
a[i + j + k]=(u - v + ZZQ)% ZZQ;
w =1ll* w * x % ZZQ;}}}}voidpolymul(int n,int*a,int*b,int*res){int ff =1, tot =0;while(ff <(n <<1)-1) ff <<=1, tot++;for(int i =0; i < ff; i++)
rev[i]=(rev[i >>1]>>1)|((i &1)<< tot -1);for(int i =0; i < ff; i++){
ta[i]= i < n ? a[i]:0;
tb[i]= i < n ? b[i]:0;}FFT(ff, ta,1);FFT(ff, tb,1);for(int i =0; i < ff; i++) ta[i]=1ll* ta[i]* tb[i]% ZZQ;FFT(ff, ta,-1);int gg =qpow(ff, ZZQ -2);for(int i =0; i < ff; i++) res[i]=1ll* ta[i]* gg % ZZQ;}voidpolyinv(int n,int*a,int*res){
res[0]=qpow(a[0], ZZQ -2);int ff =4, tot =2, gg = INV4;for(int k =1; k < n; k <<=1){for(int i =0; i < ff; i++)
rev[i]=(rev[i >>1]>>1)|((i &1)<< tot -1);for(int i =0; i < ff; i++){
tmpf[i]= i < n && i <(k <<1)? a[i]:0;
tmpg[i]= i < k ? res[i]:0;}FFT(ff, tmpf,1);FFT(ff, tmpg,1);for(int i =0; i < ff; i++)
tmpf[i]=1ll* tmpg[i]*(ZZQ +2-1ll* tmpf[i]* tmpg[i]% ZZQ)% ZZQ;FFT(ff, tmpf,-1);for(int i =0; i <(k <<1); i++)
res[i]=1ll* tmpf[i]* gg % ZZQ;
ff <<=1; tot++;
gg =1ll* gg * INV2 % ZZQ;}}voidpolyln(int n,int*a,int*res){for(int i =0; i < n; i++)
da[(i + n -1)% n]=1ll* i * a[i]% ZZQ;polyinv(n, a, inva);polymul(n, da, inva, res);for(int i = n -2; i >=0; i--)
res[i +1]=1ll* inv[i +1]* res[i]% ZZQ;
res[0]=0;}voidpolyexp(int n,int*a,int*res){
res[0]=1;int ff =4, tot =2, gg = INV4;for(int k =1; k < n; k <<=1){for(int i =0; i < ff; i++)
tg[i]= i < k ? res[i]:0;polyln(ff, tg, tln);for(int i =0; i < ff; i++)
tf[i]= i < n && i <(k <<1)? a[i]:0;for(int i =0; i < ff; i++)
rev[i]=(rev[i >>1]>>1)|((i &1)<< tot -1);for(int i =(k <<1); i < ff; i++) tln[i]=0;FFT(ff, tg,1);FFT(ff, tf,1);FFT(ff, tln,1);for(int i =0; i < ff; i++)
tf[i]=(1ll- tln[i]+ tf[i]+ ZZQ)* tg[i]% ZZQ;FFT(ff, tf,-1);for(int i =0; i <(k <<1); i++)
res[i]=1ll* tf[i]* gg % ZZQ;
ff <<=1; tot++;
gg =1ll* gg * INV2 % ZZQ;}}voidwork(){if(y ==1)return(void)printf("%d\n",qpow(n, n -2<<1));int st =1ll* y *(qpow(y, ZZQ -2)-1)% ZZQ;
y =1ll*qpow(qpow(y, ZZQ -2)-1, ZZQ -2)* n % ZZQ * n % ZZQ;
fac[0]= inv[1]= invf[0]=1;for(int i =1; i < L; i++)
fac[i]=1ll* fac[i -1]* i % ZZQ;for(int i =2; i < L; i++)
inv[i]=1ll*(ZZQ - ZZQ / i)* inv[ZZQ % i]% ZZQ;for(int i =1; i < L; i++)
invf[i]=1ll* invf[i -1]* inv[i]% ZZQ;for(int i =1; i <= n; i++)
f[i]=1ll*qpow(i, i)* y % ZZQ * invf[i]% ZZQ;polyexp(n +1, f, ans);printf("%d\n",1ll*qpow(st, n)* ans[n]% ZZQ * fac[n]% ZZQ
*qpow(n, ZZQ -5)% ZZQ);}};intmain(){
n =read(); y =read(); op =read();if(op ==0) solve0::work();elseif(op ==1) solve1::work();else solve2::work();return0;}