首页 > 代码库 > codechef 2014/12

codechef 2014/12

总是只能做4、5题,要加油啊!

1. XORSUB

You are given an array A of N integers and an integer K. Your task is to return the maximum possible value of F(P) xor K, where P is a subset of A and F(P) is defined as a xor of all values in P. If P is empty, then F(P) = 0.

题目刚出的时候没说A中的元素是<=1000的,于是就不会做了。后来这个条件出来了,就很自然能想到dp了。

在论坛看到一种高斯消元的解法(用异或来消,使得最高位成上三角),想想挺有道理的,因为得到的还是等价表示,消去前的XOR集合能用消去后的表示。消去后从大到小处理,显然后面小的数不会影响到目前已有结果,贪心即可。而且这个方法不受A[i]<=1000的限制。

补个链接 http://math.stackexchange.com/questions/48682/maximization-with-xor-operator

2. 把N个数分到K个集合,能否使得每个集合的元素和相等。N<=21, K<=8.

我是直接用搜索做的,先把元素从大到小排序,搜索时规定对于集合间按最大元素从大到小搜,集合内也按从大到小的顺序。题解是用dp做的,这个真没想到,需要注意吸收。

另每个集合的和为x, dp[k][bitmask] = 1表示能用bitmask(位压缩)表示的元素集合刚好分配到k个集合中,使得每个集合的和为x,或者分配后还剩下的元素和小于x。

for k = 0 to K - 1:    for bitmask = 0 to 2^n - 1:        if not dp[k][bitmask]:             continue        sum = 0        for i = 0 to n - 1:            if (bitmask & (1LL << i)):                sum += a[i]        sum -= k * x        for i = 0 to n - 1:            if (bitmask & (1LL << i)):                continue //there is nothing to extend            new_mask = bitmask | (1LL << i) //bitmask denoting a set with i-th element added            if sum + a[i] == x: //we can fill the k+1 th subset with elements of sum X using a set of elements denoted by new_mask                dp[k + 1][new_mask] = 1            else if sum + a[i] < x: //we can fill k subsets with elements of sum X and one subsets with sum < X using a set of elements denoted by new_mask                dp[k][new_mask] = 1if dp[K][2^n - 1] == 1:    print "yes"else:    print "no"               

复杂度O(K * 2^N * N)

3. N个范围为1~M的整数,求最大公约数在L~R之间的方式之和。M,N<=10^7

这题看了题解之后才发现应该做出来的。。。

另f(m)为1~m的n个数最大公约数d为1的方法数,则需排除d>1的情况,即f(m)=m^n-f(m/2)-f(m/3)-...-f(m/m)

到了这里原来就没继续下去了,因为觉得复杂度太高。。看了题解才发现其实不然。在算出了f(m/2)等项后,算f(m)要m次。那么求出所有项需要m+m/2+m/3+...+m/m=m*(1+1/2+1/3+...+1/m),结果是m*ln(m),按题目的时限,并不高。

结果是f(M/L)+...+f(M/R)

 

codechef 2014/12