Codechef September Cook-Off 2013

传送带

Problem A:Big Number

题意:给一个数N的二进制表示,最长100w位,然后有一些修改操作,L R,表示将L R区间内的数都取反,在每次修改操作之后输出小于等于N的且二进制表示有偶数个1的数的个数
注意到小于等于n的且二进制表示中有偶数个1的数的个数为(n+1) /2 + valid(n) ,valid(n)返回n是不是有偶数个1,那实际就是求每次更新后的数的大小,然后判奇偶性即可,维护一个二进制数的大小具备区间合并的性质,很好写。不过有个细节,b半天,还wa了好几发。。其实是自己数据没测够就交了(0的时候特判一下),导致莫名的伤感,,

Problem B is too water ....

Problem C:Game

题意:有n个数,a[1~n],a[i] <= m,现在开始游戏,每次挑选两个<=m的数给他们加上k,直到游戏不能进行为止问你这个序列最终的和的可能性有多少种

sol:因为每次都是加2*k,所以我们来转换一下题目,就是求游戏的次数的上界和下界是多少就能知道总的可能性了。

我们先求出每个数最多能被加几次。

显然,我擦,我也用上这个词语了,不行,,,我们可以发现游戏的最终状态肯定是

1:某个数的次数还没有被用完,其他所有的数都用完了(这确实显然)

2:所有的数的次数都被用完了。

而且游戏的上界立刻可以知道了,就是尽可能多的玩下去嘛,我们可以发现当最大的数mx > sum/2的时候,肯定是取不完所有的次数的,当mx <= sum/2的时候肯定是取的完的(前提是sum%2==0),反正可以推出来的结论就是当最大的数mx > sum/2的时候,最多可以进行的游戏的轮数是sum - mx,反之就是sum/2,下面会给出严谨证明。

所以现在我们开始求游戏次数的下界了,这个的话就是枚举最后剩下来的数是哪一个就好了,其他数自己搞定,如果搞不定,再让a【i】这个数来帮一下忙。

现在我们要证明mx <= sum/2 && sum % 2 = =0 的前提下,游戏进行的次数是sum/2

也就是所有的次数都会被取光,现在反证,假设有一个数剩余,如果剩余一次,不可能,因为我是两个两个减的,始终是偶数,如果剩余次数>=2,说明了从头到尾这个数都是最大值(因为如果最大值换人后最大与次大的差距就始终是1),假设还剩x次没取,当前进行了y次游戏,那么x+2*y = sum, x+y > sum/2,与原先的定义矛盾了,证毕!


Problem D:Strange Matrix

给你两个矩阵问你有多少的a[i][j] = b[i][j]

举个例子就懂了

A=

1 2 3 4 5

6 7 8 9 10

11 12 13 14 15

16 17 18 19 20

B=

1 5 9 13 17

2 6 10 14 18

3 7 11 15 19

4 8 12 16 20


一开始是以1为起始下标化简的,怎么化都化不出来,因为我化简式子的能力太弱了

我化出来是这样 (m-1) * i - (n-1)*j = n - m; (1<=i<=n && 1<=j<=m)

但随后发现改变i j的值域可以达到很好的效果即(m-1)*i - (n-1)*j = 0;其实就是两边减去n - m

i/j = (n-1)/(m-1) (0<=i<n && 0<=j< m)

假设(n-1)/(m-1)的最简形式是p/q ,那么(n-1) = p * g  (m-1) =q * g

所以i/j一共有g中方法,另外0 0 ,肯定是可以的。。

Problem E:Tree

   题意:一棵树,每次加入一个点,和已经加入的点联通,然后每加入一次都要询问一下树的直径是多少。

sol:比赛的时候一直在YY在线的做法,不过这种只有加入,没有删除的题肯定有简单做法。。唉,还是太弱了。

树的直径肯定是最远的两个点,那么我们每次加进来一个点的时候,有可能会产生新的直径,不过其中一个端点肯定是前面的某个端点,只需要根据新的最长可能长度跟原有的比较一下,然后更新最远的两个点即可。我真弱!

总结:

基础还是最重要的,不能盲目追求难度,刺激。有些题看似神奇,比如E题,但是赛后看了一些,过得人都是离线做的,而且是最普通的lca。还有那么水的A题,比赛的时候竟然看不破,逗了半天,心态还是没能放的平啊。。

https://github.com/becauseofyou/Contests/tree/master/Codechef/September%20Cook-Off%202013


你可能感兴趣的:(Codechef September Cook-Off 2013)