UNIQUE VISION Programming Contest 2022(AtCoder Beginner Contest 248)

A - Lacked Number

搞个数组标记一下。

B - Slimes

按照题意模拟一下,注意会爆int。

C - Dice Sum

应该DP一下就可以了。

我看数据范围小直接贴多项式板子然后生成函数搞了。

D - Range Count Query

用一个二维vector记录每一个值出现的位置,然后询问就是在对应的一维vector上二分一下就可以了。

E - K-colinear Line

\(k = 1\)时有无数个解。

枚举所有直线,用一个map存直线和直线过点数,最后枚举一遍所有的直线看是否符合条件就可以了。

具体就是,两点确定一条直线,所以枚举所有点对,把过这两点间的直线写成\(ax + by + c = 0\)的形式,再把直线方程归一化,就是同时除以gcd,然后确保第一个非零元素是正数。然后就可以把直线加入map了。

F - Keep Connect

动态规划。

\(i\)的基础上,推出\(i + 1\)。如果\(i\)上的两个点和更前面的点构成大于等于3个连通分量,那么用\(i + 1\)上的两个点救不回来,无解。如果是两个连通分量的话,如果\(i\)和之前不连通也是救不回来的。

现在就剩两种情况了,\(i\)上的两个点属于两个连通分量且一共有两个连通分量;还有就是一共就只有一个连通分量。那么就可以定义\(dp_{i, j, 0/1}\)为前\(i\)个位置,删了\(j\)条边,且是第0/1种情况,的方案数。

现在有3条新的边可以删除,然后枚举所有情况进行转移即可。

G - GCD cost on the tree

根据mobius反演,有\(\gcd(A_1, A_2, \dots, A_n) = \sum_{d \mid \gcd(A_1, A_2, \dots, A_n)} \varphi(d)\)

带回原式中,再把\(d\)的求和往前提,可以得到

\[ans = \sum_{d} \varphi(d) f(d) \]

,其中\(f(x)\)表示点权为\(d\)的倍数的点构成的森林中,所有路径包含节点个数之和。

然后对于每一个\(d\),用DP处理出\(f(d)\),再加起来就可以了了。

DP的话,就是dfs过程中,考虑每一条边\(u->v\),子树\(v\)中的点,和剩余其他点,两两之间的路径都回经过这一条边,所以这条边对于路径长度和的贡献是\(sz_v * (sz_{rt} - sz_v)\),其中\(sz_i\)表示子树\(i\)的大小,\(rt\)表述当前树的根。然后需要的是节点个数之和,所以每一条路径的贡献还要再加1,所以还要再加上\(sz_{rt} (sz_{rt} - 1) / 2\)

Ex - Beautiful Subsequences

单调栈加线段树。

移项可得\(max - min - (R - L) <= k\),由于是排列,所以式子左边大于等于零。

考虑不断加入右端点\(r\),然后搞出以\(r\)为右端点的区间中满足条件的个数,从而得到答案。

新加入\(P_r\)\([1, r - 1]\)区间中的\(- (R - L)\)都会减\(1\),区间加就能搞定。

新加入\(P_r\)之后,\([1, r]\)的右侧的区间的最大值,最小值可能会改变,这个用单调栈去维护,过程中借助区间加完成\(max\)项和\(min\)项的修改,具体就是入栈就是区间加,出栈就是通过区间加把之前的操作取消。

然后记录一下区间最小值以及区间最小值加\(d, d \in [0, 3]\)的出现次数。

然后区间\([1, r]\)对应的记录就是新增的答案。

posted @ 2022-04-17 22:11  _Backl1ght  阅读(63)  评论(0编辑  收藏  举报