DTOJ 4878. 零一树

题意

有一棵树,大小为nn,树上每条边都有边权,可以是1,可以是0。现有mmui,vi(uivi,1ui,vin)u_i,v_i(u_i \neq v_i, 1\leq u_i,v_i \leq n)

定义一个准路径长度pip_i等于uiu_iviv_i之间的路径和mod 2。现在问边权值有多少种方案让pip_i序列满足非递减(pipi+1p_i \leq p_{i+1} , 1i<m1 \leq i < m)。

答案需要对998244353998 244 353取模。

分值 限制 子任务依赖
1 10 2n,m102 \leq n,m \leq 10
2 20 2n,m20002 \leq n,m \leq 2000 1
3 70 2n,m2500002 \leq n,m \leq 250000 2

题解

容易发现答案为把一段前缀设为00(表示uiu_iviv_i相同),后面为11(表示uiu_iviv_i不同),这样的合法种数(设最后一个00的位置为psps,合法种数即psps个数)21*2^{连通块个数-1},问题在于如何求出合法种数。

暴力的做法是一条条连边,用并查集维护每个点与祖先是否相同,连边的同时判断合法性。原本一直在想一条条把00的边换为11的边,但这样需要撤销一条之前的边再连上一条新边,对并查集的影响难以维护。

发现上面的问题在于并查集仅能支持撤回刚加入的边,而不能撤回之前的边。对于直接从左往右考虑不好做的问题,应该考虑分治:对于当前区间,先把左半部分全部设为00,向右递归计算(即psps在右半边)后撤回,然后把右半部分全部设为11(即psps在左半边),向左递归计算后撤回。由于这样保证撤回的都是刚加入的边,用启发式合并维护并查集回退即可,效率O(nlog2n)O(nlog^2n)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章