比赛链接: http://codeforces.com/contest/396
代码链接: https://github.com/9974/Codeforces/tree/master/232div1
A
分解质因数, 对于每个质数单独考虑,假设质数2的指数为m, 那么我们要做的就是求 把m个2分配给n个数 的情况数
用高中的挡板法得 C[m+n-1][n], 每个质数是相互独立的,所以都乘起来就好了。
B
u和v的变化情况为 (2,3) , (3,5) (5, 7) ........ 在完整的一段中 对为(u,v) 有v-u个,把这些合并一下 我们可以化简成1/u - 1/v。 考虑完整的一段,
对于 n在完整段中 找到 所在的对(u,v) , 那么最后答案为 1/2 - 1/v , 对于不完整的, 完整的一段先处理一下,剩下来的几个数单独处理。
C
线段树:首先,很明显的是树转链, 对于-i*k的那部分更新,把它转化一下,看成是以1节点(根)下来的更改,那么每个点的值必然会增加减少dep[v]*k(v为询问的根节点),我们不妨把它跟x的那部分并起来加上去, 用一个线段树维护A区间和, 同时转化以后,我们再用一个线段树B维护k的区间和, 最后v所在的A.val减去v所在的B.val*dep[v]就是答案
树状数组: 这里由于 询问是单点的,所以也可以用2个树状数组维护一下前缀和, 对于区间[l, r] + v 我们可以通过add(l,v) add(r+1, -v) 这两个操作完成更新, 询问的时候询问当前点的前缀和就可以了。
D
根据数位来实现枚举到了所有的字典序,做过数位dp的应该很懂。
枚举每个位k。我们可以分3种情况来计算收益(即答案)
1. 前面k-1数字与所给的序列相等, 第k位不相等。统计 第k位产生的收益
假设前面比a[k]小的数有cnt个,那么 对于k位 我们可以有 a[k]-1-cnt个选择。k位可以选剩下来的数的 第一小,第二小........ 第 a[k]-1-cnt小的数, 所带来的收益分别是 0*(n-k)!,1*(n-k) ..... n-k*(n-k)! 总收益为 (n-k)!*(n-k-1)*(n-k)/2
2.前面k-1数字与所给的序列相等, 第k位不相等。 统计第k位以后的全排列产生的收益
对于1---n的n个数的全排列, 考虑每个点对(a,b)在全排列中的 先后顺序 , 产生收益的情况是总情况的一半,一共有n*(n-1)/2个点对 总收益为n*(n-1)/2 *n! / 2 = n*(n-1)*n! / 4
3.前面k-1个位部分前缀相同 。 前k-1部分相同个的位跟k之后(包括k)的位产生的 收益
当放到第i位后就能知道后面比它小的数有多少个(无论后面怎么排),个数为w, 那么i位置之后的计算都要算上w*枚举的情况数, 所以我们可以用一个变量pre来维护 第k位之前 在情况数为1的时候的第1,2....k-1位带来的总体收益。
前缀和可以用树状数组维护
Codeforces Round #232 (Div. 1)(A,B,C,D),布布扣,bubuko.com
Codeforces Round #232 (Div. 1)(A,B,C,D)
原文:http://blog.csdn.net/auto_ac/article/details/20147273