可憐的出題人(跟九條可憐沒有關係)要給 n
nn 個地方出題。
但是出題人太累了,他決定把以前給這些地方出過的題重新搬一搬。
這 n
nn 個地方以 1,…
,n
1,\dots,n
1,…,
n 編號。出題人總結出了他們之間的聯絡,是乙個樹形。如果出題人把以前給第 i
ii 個地方出的題搬到第 j
jj 個地方,那麼他希望 i
ii 和 j
jj 在這棵樹上的距離越長越好。
於是出題人需要決定乙個排列 p1,
…,pn
p_1,\dots,p_n
p1,…,
pn ,要求最大化
s =∑
i=1n
dis(
i,pi
)s=\sum_^n \mathrm(i,p_i)
s=∑i=1
ndi
s(i,
pi)
這個 s
ss 越大,出題人可能受到的損失(被指出是原題於是被上某乎或扣工資等)就越小。
有時候出題人還想知道在最大化 s
ss 的前提下自己有多少種搬題的方案。即有多少排列 p1,
…,pn
p_1,\dots,p_n
p1,…,
pn,使得 s
ss 最大。
由於這個數可能非常大,你只需要輸出其對 998244353998244353 取模的結果。
首先考慮如何最大化sss。
我們只需要找到重心作為根,求出2∗∑
i=1n
depi
2*\sum_^n dep_i
2∗∑i=1
nde
pi即為答案,不會有更大的答案,因為可以對於每一條邊考慮,貢獻的權值最多為2
∗min(
sz[x
],n−
sz[x
])
2*\min (sz[x],n-sz[x])
2∗min(sz
[x],
n−sz
[x])
,其中該條邊所連線的遠根點為x
xx,在上面的方案中達到了最大值。
方案數顯然就是要在重心為根時,將重心的每乙個兒子的子樹點放到其他的兒子子樹中。
顯然可以容斥,記s
ss為選擇放在當前子樹的集合,a
ia_i
ai表示第i
ii棵子樹有多少個選擇放在當前子樹,s
is_i
si表示第i
ii棵子樹有多少個點。
則有答案式子∑s(
−1)∣
s∣(n
−∣s∣
)!∏i
=1mc
siai
psia
i\sum_ (-1)^ (n-|s|)!\prod_^m c_^p_^
s∑(−1
)∣s∣
(n−∣
s∣)!
i=1∏
mcs
iai
ps
iai
後面使用dp或者ntt來優化即可。
#include
using
namespace std;
const
int n=
200010
,mod=
998244353
;struct edges[n<<1]
;int first[n]
,len=
0,n,t,sz[n]
,mmin=
1e9,pos=
0,mmax[n]
,fac[n]
,inv[n]
;int f[n]
;void
ins(
int x,
int y)
;first[x]
=len;
}int
ksm(
int x,
int t)
return tot;
}void
dfs(
int x,
int fa)if(
max(mmax[x]
,n-sz[x]
)max(mmax[x]
,n-sz[x]
),pos=x;
}long
long tt=0;
void
dfs_2
(int x,
int fa,
int dep)
}int
down
(int x,
int y)
intmain()
int ans=
0,t=1;
for(
int j=
0;j<=tot;j++
) ans=
(ans+
1ll*t*fac[n-j]
%mod*f[j]
)%mod,t=
(t==
1?mod-1:
1);printf
("%d\n"
,ans)
;}
LG模擬賽 3 T2 簽到題
你面前有乙個來歷不明的 01 序列 a 0.m 1a a0.m 1 為了調查明白這東西是從 冒出來的,你想知道有多少個整數 x 0,l x in 0,l x 0,l 滿足 i 0,m 1 popcount x i mod2 a i forall i in 0,m 1 operatorname x i...
LG模擬賽 2 T2 kk公司,貪心合併
kk 公司有很多 kk,還有很多 cy。除了老闆之外,每個人都有乙個直屬的上司。某天他們想要拍一張合照。出於尊敬,每個人都必須站在自己的上司的右側 不需要緊挨著 但是老大認為 kk 站在 cy 的左邊不好。合照中每有一對 kk 和 cy,使得 kk 站在 cy 的左邊 不需要緊挨著 那麼老大的憤怒值...
弱省互測 2 t3
給出 n 個01位元組和 m 個01位元組,要求用後者去匹配前者,兩個串能匹配當且僅當除了每個位元組末位不同,其他位都要相同。問匹配後者至少有多少個末位不同。1 le m le n le 2.5 times 10 5 首先我們可以用kmp計算出能匹配的位置,然後單獨考慮末位不同的情況。我們將末尾的位...