T1:不难想到把w和z从小到大排序,然后枚举每一次会议,然后用一个指针i维护最后一个小于等于当前z的w在哪个位置。因为已经排了序,所以i是单调递增的。
然后问题就变成了在1~i中求在原序列中的位置在x~y的答案。那么这个可以用线段树维护。
我们每一次把i往后移时都把当前i所对应的pos加入线段树,然后我们来看看怎样求答案:p=sum(pos[i])/m,对于p,显然我们只需要维护pos的和还有个数就行了。而k=sum((pos[i]-p)^2)*m
=sum(pos[i]^2-2*p*pos[i]+p^2)*m
=(sum(pos[i]^2)-2*p*sum(pos[i])+p^2*m)*m
那就多维护一个pos^2的和就行了。
T2:首先我们发现,如果两个点之间的路径为奇数,那么这两个点到根的路径一定是一奇一偶。进而知道若两点之间的路径是合法的,那么这两个点的距离就是它们到根的距离的和(因为公共部分可以抵消)。所以,我们便得到了以下算法:
预处理出每一个点到根的距离和奇偶性,然后把奇数点的距离保存在数组a里,偶数点保存在数组b里,那么问题就变成了求a[i]+b[j]的第k小值。这是一个经典问题,做法是先把所有a[i]+b[1]加入一个小根堆里,然后每一次取出一个最小的a[i]+b[j],然后把a[i]+b[j+1]加入小根堆。第k次取出的数就是答案了。
总结:要记下求第k大的a[i]+b[j]的方法。
T3:暴力模拟,注意细节。
T4:首先要发现一个性质:要尽量使异或出来的高位为1。因为无论后面几位是什么,高位为1的值一定比为0的值大。然后这题就可以做了。
首先从大到小排序,然后把每一个数的二进制状态求出来。之后枚举每一个数,然后求出其他数与这个数异或的最大值。求法就是从高到低枚举每一位,然后求出与当前这一位当前这一位异或为1的合法区间(已经排好序了,所以是区间),注意低位区间要满足高位区间。最后在求出来答案就行了。