51nod算法马拉松20总结

好吧这也称不上是一个总结
只不过旷掉了一场思想上AK的模拟赛过来淦题而已
结果发现好像比上次要难的样子?(还是我变弱了?)
实力原因不会做的题就不写了
题目链接
A:
考虑每一条边对答案贡献
也就是这条边所连接的两个联通块中都至少有一个点被选择的方案数。
设其中一个联通块的大小为size,则另一个为n-size
考虑容斥,用总方案数减去全部都在某一边的方案数。
那么 Ans=CknCksizeCknsize

B:
我们发现对于一段区间,我们可以O(1)算出它的权值
设An[i]表示1~i这段区间的权值,Sum[i]表示前缀和
那么区间l~r的权值就是

An[r]An[l1](Sum[r]Sum[l1])(l1)+Sum[l1](rl+1)

化简一下
An[r]An[l1]Sum[r](l1)+Sum[l1]r

我们可以把值相同的放到一起算
发现这个式子只和每个区间的端点有关,那么我们可以枚举右端点,然后判断它有多少个左端点并且记录所有左端点的和,然后对答案贡献。
同理也可以枚举左端点,然后就解决了。

C:
不知道大佬们是怎么做的,反正我的方法比较辣鸡
设Fi表示忽悠了i次的期望忽悠事件数,那么我们有 Fi1n 的概率忽悠到之前忽悠过的事件, nFi1n 的概率忽悠到新的事件,那么

Fi=Fi1nFi1+nFi1n(Fi1+1)

化简一下
Fi=n1nFi1+1

然后矩阵乘法快速幂就好了
还有我们把这个式子写出来
F1=1

F2=n1n+1

F3=(n1n)2+n1n+1


归纳可得
Fm=(n1n)m1+(n1n)m2++1

等比数列求和得
Ans=n(1(n1n)m)

不过都需要卡卡精度
反正我还没有卡过去,据说C++用_float128能过去

D:
首先N^2的转移大家应该都会写吧。。。
然后我们考虑如果是一条链怎么做?
因为下标是递增的,所以我们发现,如果F[i]是由F[la]转移过来的,那么F[i+1]一定不会由F[la]之前的转移过来。
证明感性理解一下就好了吧。。。
然后我们就成功吧一条链变成O(n)的了=w=
然后再把这个算法上树就过掉了?!
毕竟有一个p这个指数在这里,想卡也卡不掉(排名前几的都是直接搜前100个的)
你说p=1?!那就可以特判一下嘛~~

你可能感兴趣的:(总结)