https://codeforces.com/contest/2035/problem/F
题意:给一棵树,每个点上有一个点权。可以进行以下操作无数次:
若是第x次操作,则可以操作第(x-1)%n+1个结点。选择该结点及其子树上的一个点,将其点权加一或减一。
问最少多少次能使得所有点权为0。
1.注意到,如果设当前经过了x次操作,设dp[u]为该节点及其子树还需要多少次操作才能全部变为0。则u节点能操作$[x/n] + (x\%n >=u) = has\_u次,dp[u] = \sum dp[son] + a[u] - has\_u$。$当dp[u]\leq 0时,根据意义令dp[u] = (-dp[u])\%2即可。$
2.注意到ans是让dp[root]为0的最小的数。
3.注意到该问题总是有解的,考虑子问题:不考虑dp取负模2,让dp[u]全部小于等于0。
设操作了t次,这个操作显然是有下界的。在此基础上,所有点权非0即1。这个时候对于某个节点,可以进行n次操作,rt的操作作用于该节点而其他节点操作做用于自身。这样可以调整任意一个节点于其他节点的奇偶性,通过最多n方次操作可以使得左右子节点的奇偶性一样。最后如果为1,通过n次操作修改为0,最后修改rt为0。总之必有解。
4.注意到如果x能使得dp[root]为0,则x+2n一定可以,于是只需要枚举2*n的余数,再二分最少需要多少轮即可。
5.dfs容易超时,用反拓扑序处理dp数组
https://codeforces.com/contest/2035/submission/288411937