提高模拟赛题解
图
对于一张颜色已知的图,为了最大化图的边数,我们会在不同颜色的点之间连上一条边。
边数为(为颜色总数,是颜色为的点数):
30分:
枚举每个点选什么颜色,然后计算一下边数。时间复杂度
明显平均分最优。
60分:
枚举m,然后计算上述式子。时间复杂度
100分:
发现可以除法分块,对于上取整和下取整分开来计算即可。
然后就是除法分块裸题。
位运算
30分:
枚举,然后计算二进制下的个数。
或 先预处理出,表示在二进制下的个数。时间复杂度
不用计算的话可能被卡。
60分
在30分的基础上分段打表,时间复杂度。
先考虑一下,的情况。发现答案相当于是有位可以随意选的和 加上。
位可以随便选,考虑。
我们可以先枚举二进制中的个数是。主要是要想到能怎么分割,发现只要记录一下余数即可,就是余数了就加。然后就是一个很自然的,表示前位,选了位,余数是的方案数。表示前位,选了位,余数是k的答案。
int x=(Pow[i]/bit)%mod,y=Pow[i]%bit; if(y+k>=bit) { Add(f[i+1][j+1][y+k-bit],f[i][j][k]); Add(g[i+1][j+1][y+k-bit],g[i][j][k]); Add(g[i+1][j+1][y+k-bit],f[i][j][k]*(x+1)); } else{ Add(f[i+1][j+1][y+k],f[i][j][k]); Add(g[i+1][j+1][y+k],g[i][j][k]); Add(g[i+1][j+1][y+k],f[i][j][k]*x); } Add(f[i+1][j][k],f[i][j][k]); Add(g[i+1][j][k],g[i][j][k]);
80分:
如果不是的情况的话还要考虑压着限制的情况,可以强制前几位压着限制再做,复杂度。
100分:
在80分的情况下,发现是几乎一样的,就是不需要每次都因为强制了一些数就重新,完全可以和起来一起算。时间复杂度。
树
10分:
先预处理出每个点对的距离。然后枚举点对,计算答案。
时间复杂度
30分:
两种方法
- 枚举点对,倍增找到分割点,然后分类讨论一下,细节较多,需要预处理的东西也多。时间复杂度
- 需要稍微转化一下题目,其实就是删掉一条边,求两部分的带权重心值的和。
带权重心有两种做法。一种就是换根DP。另一种就是考虑每条边的贡献,就是 ,这里的是指点权和,为所有点的点权和,。
50分:
菊花。
有两种情况,
- 有一个点在中间,那么另一个点就是最大的点。
- 按照排序,枚举一个点(假设边权为),强制另一点的边权要,那么另一个点就是最大的点。
70分:
链。
考虑30分的考虑每条边贡献的做法。线段树维护和 。然后就可以枚举断哪条边,对两部分求一下 。就是对于 的求 ,对于 的求。
100分:
在70分的情况下,考虑断掉树上的一条边会怎么样。发现除了到根路径上的边,其余边的都没改变,仍能用70分的做法求。但到根路径上的边变成了。,分成和两部分来求解。用线段树维护和,即可。