Tree XOR

引理:对一个点最多只会操作一次

证明:如果对一个点操作了多次,不妨设每次操作的数是\(c_1,c_2,...,c_k\),那么这个点对答案的贡献就是\(s\times (c_1+c_2+...+c_k)\);而我们如果对这个点只操作一次,操作数为\(c=c_1⊕c_2⊕...⊕c_k\),那么显然也满足题意,并且这个点对答案的贡献为\(s\times c\)。由于异或是不进位二进制加法,显然后者的贡献更小,所以我们对一个点只会操作一次

思路一:充分利用异或的无顺序性

对任意一种方案,我们的操作顺序是从儿子往父亲依次操作,这样的话,在即将操作点\(u\)的时候,他的子树的所有节点的权值一定是相等的(否则的话,我们接下来无论如何操作都不可能再让这个子树中的所有节点的权值相等了,因为我们接下来不会再操作这个子树了)并且都为\(a_u\)(否则的话,我们操作完\(u\)后,\(u\)的权值一定与其子树的权值不同,接下来的操作也不可能让他们相同,因为我们接下来不会再操作\(u\)及其子树了)

于是我们设\(f[i]\)表示将\(i\)的子树的所有点的权值都变为\(a_i\)的最小代价,有

然后再换根DP即可

思路二:位运算的经典的按位考虑

仍然利用引理,设一个点在最终的方案中被操作的数为\(c\),则贡献为\(s\times c\),将\(c\)进行二进制拆分,便可考虑每一位的情况

假设当前考虑的是第\(i\)位,我们从根节点开始考虑。如果根节点的某个儿子在这一位与根节点相同,那么无论根节点怎么操作,他的儿子一定都是不操作的(否则的话根节点就与其的权值不同了),如果根节点的某个儿子在这一位与根节点不同,那么这个儿子一定是会操作的;拓展一下就有对任意\(u\),如果\(u\)的父亲的权值在这一位与\(u\)的权值相同,那么\(u\)一定不会操作,否则的话\(u\)一定会操作

于是仍然可以设计一个换根DP,跑出以\(u\)为根的时候的所有点的贡献,由于我们枚举了位,所以最后用贡献乘以\(2^i\)即可

posted @ 2024-03-29 22:22  最爱丁珰  阅读(1)  评论(0编辑  收藏  举报