Codeforces Global Round 1[CF1110]
A,B都没什么好说的。
C. Meaningless Operations
题意:多次询问,求 $f(a)=\max_{0 < b < a}\gcd(a\oplus b,a & b)$。
先用二进制表示 $a$,显然有 $\gcd(a\oplus b,a& b)\leq a\oplus b$,设 $a$ 的最高二进制位为 $x$,则 $a\oplus b\leq 2^{x+1}-1$。
可以发现,当 $a\not = 2^{x+1}-1$ 时,$a\oplus b$ 能取到最大值。此时有:$a+b=2^{x+1}-1$,则 $a& b=0$,因此 $\gcd$ 也能取到最大值。
那么当 $a=2^{x+1}-1$ 时,$a\oplus b=a-b,a& b=b$,则 $\gcd(a\oplus b,a& b)=\gcd(a-b,b)=\gcd(a,b)$,找到 $a$ 的最大不是本身的因子即可。
D. Jongmah
如果出现了三个 $(x-1,x,x+1)$,则可以用 $(x-1,x-1,x-1),(x,x,x),(x+1,x+1,x+1)$ 代替。
也就是一种合法的方案一定能转换成每种 $(x-1,x,x+1)$ 不超过 $2$ 个的形式。
设 $f_{i,j,k}$ 表示考虑到第 $i$ 位,$(i-1,i,i+1)$ 有 $j$ 个,$(i,i+1,i+2)$ 有 $k$ 个的最大值,然后DP即可。
1 | memset(f,-1,sizeof(f)); |
E. Magic Stones
题意:给一个序列 $c$,每次选一个 $i\in[2,n-1]$,将 $c_i$ 变成 $c_{i-1}+c_{i+1}-c_i$,问是否能将 $c$ 变成序列 $t$。
这种题通常都是差分或者前缀和就搞出来了。
首先必须要有 $c_1=t_1,c_n=t_n$。
我们进行差分,设 $a_i=c_{i}-c_{i-1}$,发现上述的操作实际上是在交换两个相邻的 $a_i$。题意转换成你可以交换任意相邻的数字,使得最后序列等于某个序列,排个序就没了。
F. Nearest Leaf
题意:
给定一棵带边权树,满足按照节点编号从小到大的顺序dfs得到的dfs序 $dfn_i=i$。
多次询问,可离线,求 $[l,r]$ 中所有的叶子结点点 $v$ 最近的距离。
$n,q\leq 5\times 10^5$
那就离线吧,把询问挂到树上,然后在dfs时处理询问。
假设你从 $u$ 开始经过了一条边 $(u,v,w)$,$w$ 表示权值,那么有些叶子结点的距离就 $+w$,有些就 $-w$,并且 dfs 序都是 $O(1)$ 段区间。由题目的性质知道对于的节点编号也是 $O(1)$ 段区间。
那么用线段树,把非叶子结点的距离设为 $+\infty$ ,然后随便打打标记就好了。
时间复杂度 $O(n\log n)$。
1 |
|
G. Tree-Tac-Toe
我们假设先不考虑刚开始就是白色的点。
首先显然的是,黑色不可能赢,因为如果黑色有必胜策略的话,白色能先走它的这个必胜策略。
那么看什么时候白色能赢。
设点 $i$ 的度数为 $deg_i$。
第一种情况:显然有,若存在 $i$ ,使得 $deg_i\geq 4$ ,则白色必赢。
第二种情况:接下来考虑度数是 $3$ 的点,发现如果他所连的三个点中存在至少两个不是叶子结点,那么白色也必胜了。
第三种情况:排除了上面两种情况以后,剩下的只能是一条链,然后在链的第二个和倒数第二个的点上最多再挂一个点的形式。
如果这两个点上都没再挂一个点,那么最后只能是平局。
最后只剩下这种:
可以发现,当直径上点的长度是奇数的时候,白色必胜。
那么最后来考虑刚开始就有白色的情况。
它相当于你把这个点染成白色以后,必须要有一步黑色的操作,且这个黑色的操作不能影响到原来的点。
也就是必须设计一个东西,然后挂在这个被染成白色的点上面。
显然可以这样设计:
当你选了白点以后,如果黑色不选这个中间的点,那么下一步白色选它,黑色就输了。
那么这题就能做了。时间复杂度 $O(n)$。
1 |
|
H. Modest Substrings
题意
求一个字典序最小的长度为 $n$ 的数字串,满足不含前导零的子串所表示的数字在 $[l,r]$ 内的子串数目最多。输出这个子串数目和字符串。
$1\leq l \leq r \leq 10^{800},n\leq 200$,时限 5s,空间 1G。
题解
如果 $r-l$ 比较小的话,我们就可以把所有在 $[l,r]$ 内的数字建出一个AC自动机,然后在上面跑DP就好了。
类似于数位DP,如果某个时刻你选的数字已经脱离限制了,那么以后随便填就都可满足了。比如 $l=227$,$r=403$,第一位选了 $2$,当第二位选了 $3$ 的时候,后面随便乱选都满足在 $[l,r]$ 里面了(对应在AC自动机上是一个满10叉树)。
我们找到哪些前缀会在选完前缀的最后一个数后脱离限制。发现最多有 $800\times 10 \times 2=16000$ 个这样的前缀,找这些前缀分类讨论一下即可找到。
要注意,脱离了限制不代表一定可以满足在 $[l,r]$ 内,这个前缀还需要加上一定个数的字符才能在 $[l,r]$ 内。
然后对这些前缀建立AC自动机,然后在AC机上进行DP。
设 $f_{i,j}$ 表示考虑到第 $i$ 位,当前在AC自动机的第 $j$ 个点上的最值。
考虑往后转移,设此时字符串是 $s$,你在后面填上一个字符 $c$,看这个此时这个字符 $c$ 的贡献。
这个贡献相当于枚举 $s+c$ 的后缀,看这个后缀是否脱离限制,且后面能给它加足够的点来完成。那么设 $h_{j,k}$ 表示节点 $j$ 的点的fail链的所有点中,当中有 $h_{j,k}$ 个前缀满足需要再加 $k$ 个字符才能在 $[l,r]$ 内。
那么这个DP就是:$f_{i+1,ne_{j,c}}=\max{f_{i,j}+\sum_{k\leq n-i-1}h_{ne_{j,c},k}}$。
$h$ 做个前缀和即可快速转移。
时间复杂度 $O(nm\Sigma)$,其中 $m$ 为 AC自动机点数,$\Sigma$ 为字符集大小。
输出方案倒退回去再正推贪心即可。
程序
1 |
|