比赛链接:https://codeforces.com/contest/1857
A. Array Coloring
题意:一个数列,问能否分成两个和的奇偶性相同的集合
思路:因为偶数不改变奇偶性,咱们就统计奇数的个数,能平分成两组就行
B. Maximum Rounding
题意:给一个数,每次可以找一位数不四舍可五入,然后把这个位及后面的数都变成零,找到最终能到达的最大的数
思路:显然从最低位开始操作才能到达最大的数,所以就这么做
C. Assembly via Minimums
题意:给一个转化后的数组b,求一种可能的原数组a,其中b是由\(min(a_i, a_j) (i < j)\)组成的
思路:其实min(ai, aj)就是a数组中的数两两进行比较,因此,最小的数会在b中出现n-1次,第二小的出现n-2次,以此类推,并且推下去发现最大的数是不会在b中出现的,就随便找个数糊弄就行
D. Strong Vertices
题意:给两个数组,如果\(a_u - a_v >= b_u - b_v\),就有一条u到v的有向边,问有多少个出度为n-1的点
思路:O(n^2)的暴力是过不了,即使算上只要有一次不成立就break,就算是想如果条件不满足,说明反向成立也就是有个1/2的常数,要换思路。我们稍微改变一下条件原式其实就是\(a_u - b_u >= a_v - b_v\),预处理一下得到数组c, 其中\(c_i = a_i - b_i\),那么,我们要找到出度为n-1的点,也就是有一个数比其余n-1个数都大于等于,其实也就是找最大数有几个
E. Power of Points
题意:给一个数组x,对每个\(s=x_i\),和原数组组成n个区间\([s, x_0], [s, x_1]...\),对\(1-10^9\)中每个数,\(f(i)\) = 覆盖\(i\)的区间数,求\(\sum_{i = 1}^{10^9} f(i)\)
思路:其实就是求n个区间的大小,逐个去搞要\(O(n ^ 2)\),不好,我们先排个序,然后梳理一下公式,对每个\(s=x_idx\),
\(\sum_{i = 1}^{10^9} f(i) = \sum_{i = 1}^{n} |max(s, x_i) - (min(s, x_i) - 1)|\)
\(=\sum_{i = 1}^{idx} {s-x_i+1} + \sum_{i = idx+1}^{n} {x_i-s+1}\)
\(=n + s*(idx-(n-idx)) - \sum_{i = 1}^{idx} x_i + \sum_{i = idx+1}^{n} x_i\)
\(=n + s*(2 * idx - n) - \sum_{i = 1}^{idx} x_i + \sum_{i = idx+1}^{n} x_i\)
这样就很明显了,后两个求和用前缀和求取即可
F. Sum and Product
题意:给个数组,对于每次询问x, y,找到有多少种满足\(a_i + a_j = x, a_i * a_j = y\ (i < j)\)的组合
思路:其实两个式子稍微联立一下就能得到\(a_i\)和\(a_j\)的值,分别是\(x_1 = \frac{x + \sqrt{x^2 - 4y}}{2}\)和\(x_2 = \frac{x - \sqrt{x^2 - 4y}}{2}\),但是直接最好让\(x_2 = x - x_1\)减小误差,不然真的烦人内,然后分不存在、\(x_1=x_2\)、\(x_1!=x_2\)三种情况用乘法原理算组合。或者,其实看这两个解多半就知道是一元二次方程了,让\(\Delta = x^2 - 4y\),分无解、同解、两解分情况套路也可以。
G. Counting Graphs
题意:给一个最小生成树,可以往上面加权值不超过s的边,但是不破坏原最小生成树,问有多少种情况
思路:下面是我拙劣的理解:我们从生成最小生成树的思路出发,prim显然是指望不上,看看kruskal,它的想法是从小到大枚举边,用并查集维护最小生成树,那么这说明我们在加边的时候,是不能加比点相连原边权值小的边,只能加\([w_i, s]\)的边;
而且,不能连已有边权比加的边权大的点,并且这个点不能连回来会重复,所以我们只能连权值比\(w_i\)小的边,于是我们不如就在建最小生成树的过程中来计算;
在连两个点之前,这两个点一定是不连通的,分属于两个连通块,这两个连通块之间,可以随意连接边权在\([w_i, s]\)的边,除去已有的uv间的边,有size[Find(u)]*size[Find(v)]-1中可能,于是对于每条边,就有\((s - w_i + 1) ^ {size[Find(u)]*size[Find(v)]-1}\)的贡献。