Wannafly挑战赛1

地址:https://www.nowcoder.com/acm/contest/15#question

A(树形dp)

分析

  dp[i][0],dp[i][1]分别表示以i为根的子树中,有多少个点到i的距离为偶数、为奇数

  那么每次merge i点和i点的某个儿子u的时候,统计一下答案就行了,ans+=dp[i][0]*dp[u][1]+dp[i][1]*dp[u][0]

  时间复杂度$O(n)$

B(枚举)

分析

  每次枚举一个区间(i,j),统计1~i-1中有多少个区间异或值和(i,j)的异或值相同

  可以i从小到大枚举,维护一个权值数组,将1~i-1所有区间的异或值丢到权值数组中

  计算一个区间的异或和可以通过异或前缀和预处理来$O(1)$计算

  时间复杂度$O(n^2)$

C(虚树上bfs)

分析

  假设我们当前询问中的关键点的lca是u,那么容易发现答案要求的那个点一定在u子树内(因为若在子树外一点x,那么十分容易证明u点比x点更优)

  进一步分析,发现答案要求的那个点一定就是所有关键点中距离最远的两个点的路径中点

  那么现在只需要求出关键点中最远的两个点的距离就行了

  根据题目输入的范围,很明显需要求出虚树,然后就等价于在虚树上询问相距最远的两个点

  也就是找这个虚树的直径,在虚树上两次bfs就行了

  时间复杂度$O(n+\sum {|S_i|})$

D

待填坑

E(线性基)

分析

  很神奇的题

  我们可以把每个点周围相连的边边权都异或起来作为这个点的点权,那么如果两个相邻点点权相异或,那么它们相邻的那条边异或了两次,相当于没有异或,即不在割当中!

  也就是说这n个点权,我们任取k个点点权将其异或,那么最终结果就表示一个割的方案!

  那么问题就转换成了有n个数,这n个数异或出的不同结果的和是多少

  先求出线性基,设秩为r

  枚举每一位,看看是否有某个基该位是1,如果有1,那么这些基能异或出的2^r个数中,该位是1的一定有一半,所以该位的贡献就是$2^{r-1}*2^i$

  结果long long就能存下,输出前9位唬人的

  时间复杂度$O(32n)$

posted @ 2017-10-14 14:22  Chellyutaha  阅读(325)  评论(0编辑  收藏  举报