NOI2018情报中心

这题当场想了1h左右,自以为会正解。
当时的想法,在S2部分是对的,但在S1部分是错的。
在S1部分,我试图使用轻重链路剖分,轻儿子暴力,重链上就像链的部分分一样做。但事实上两条lca在同一条重链上的路径,他们的交可能还从重链上伸出去一点,然后我就gg了。
事后还是花了些时间才想出S1的正确做法。
大概就是对于两条链(u1,v1,lca1,lca2)和(u2,v2),在lca(u1,u2)处统计他们的贡献。
显然lca1和lca2均为lca(u1,u2)的祖先,所以可以以深度从小到大为序建线段树。
在u1的线段树上插入 l c a 1 lca1 lca1,在u2的线段树上插入 l c a 2 lca2 lca2,直接线段树合并即可。
可能有些比较simple但有意义的细节,诸如int merge(int x,int y)时一定要拿(x的左儿子与y的右儿子)还有(x的右儿子与y的左儿子)分别更新答案。
S2部分当场就想出来了,不过没来得及写。
对于每条链(u,v),挂在lca(u,v)的vector下。
枚举每个点x作为lca,在枚举他的一个儿子y。
将以x为lca,一端在y的子树中的链(u,v),在y子树中的那个端点u,拿出来建虚树,然后可以发现另一侧的问题跟CTSC2018D1T2差不多。
可以直接上边分树合并。
但更简易的做法是像维护两个点集直径,或是WCT1一样。
其实 d e p u + d e p v − d e p l c a dep_u+dep_v-dep_{lca} depu+depvdeplca也具有直径的性质,不是那么显然,但可以分类讨论证明。
一个猜到这个性质的方法是注意到CTSCD1T2暴力那么难卡
比较明显的是题解中的转化,链交两倍=两条链长+dis(u1,u2)+dis(v1,v2)。
反正我是直接用 d e p u + d e p v − d e p l c a dep_u+dep_v-dep_{lca} depu+depvdeplca来做的
然后题解在S2部分还是用了启发式合并。
本来合并两个点集直径常数就已经很大了,还乘个log就更慢了。
常数更小的做法就是前述的建虚树。
最后总复杂度是 O ( T ( n l o g n + m l o g n + m ) ) O(T(nlogn+mlogn+m)) O(T(nlogn+mlogn+m))
log在预处理ST表lca和线段树合并上。
考场上看到这题还是挺恶心的,因为除非能快速写出S1和S2两个部分,否则要写一堆部分分,特别是其中链的部分分和c=0的部分分,跟S1,S2无直接联系,但在没把握同时写出S1,S2的情况下=又不得不写。
我的建议是是把链的部分分丢进S1里,c=0的部分分丢进S2里。
这样单写链和c=0的得分不变,但去写半个正解的人就会赚一些。
甚至可以削弱最后一档分和第一档分,分给前面的S1和S2,毕竟本来S1和S2就是正解的一半。
码了整整5.4K,WcT1我也就写了5k,CTSCD1T2我也就写了3.5K。
二合一还是很毒的。

2018.11.29upd:
晚上胡思乱想的时候突然意识到好像只写S1,就可以直接过掉链的部分分,加以微量改动就可以拿到c=0的分。
之所以会有前面的吐槽,还是因为自己太菜,本来在赛场上想出的S1做法就是假的,而且没分析出部分分之间的关联性质,还是要引起警惕,谨防以后发生类似的事。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值