\[\text{给定一个长为 } n \text{ 的正整数序列 } a \text{,和一个正整数 } k \text{。求出:} \\ \max_{\substack{i - j \geq k}} \gcd(a_i, a_j)
\]
时间复杂度 \(O(n\lnn)\)。
考场上没想到这么好的做法,写了一个分解质因数,然后组合成所有可能的数值,放到 map 里面,判断就可以了。\(O(n\sqrt n)\) 跑不满大概 \(3\times 10^8\)。
\[\text{给定一个长为 } n \text{ 的 01 字符串 } S \text{。求有多少个长为 } n \text{ 的字符串序列,满足:} \\ A_0 = S, \quad A_n \text{ 为空,} \quad A_i \text{ 长度为 } n - i, \\ \forall 1 \leq i \leq n, \, A_i \text{ 是 } A_{i-1} \text{ 的子序列。} \\ \\ \text{定义:} S \text{ 是 } T \text{ 的子序列,当且仅当可以从 } T \text{ 中删去一些字符使之变为 } S \text{。}
\]
想到了区间 dp,但是不会分离左右贡献,学到了。
我们假设区间的最后一步操作是 \(k\),那么你就可以枚举 \(k\) 并递归左右操作了,最后乘上选择的组合数就可以了。
\[\text{给定一个 } n \times n \text{ 的网格图,点的编号从 } (1,1) \text{ 到 } (n,n)。 \\
\text{对于所有 } 1 \leq i < n, 1 \leq j \leq n, \text{ 存在一条从 } (i,j) \text{ 到 } (i+1,j) \text{ 的无向边,边权为 } 1。 \\
\text{对于所有 } 1 \leq i \leq n, 1 \leq j < n, \text{ 存在一条从 } (i,j) \text{ 到 } (i,j+1) \text{ 的无向边,边权为 } 1。 \\
\text{此外,还有 } m \text{ 个四元组 } (a_i,b_i,c_i,d_i),\text{ 满足 } a_i \neq c_i \text{ 且 } b_i \neq d_i, \\
\text{对于每个四元组,存在一条从 } (a_i,b_i) \text{ 到 } (c_i,d_i) \text{ 的无向边,边权为 } |a_i-c_i| + |b_i-d_i| - 1。 \\
\text{求所有 } \frac{n^2(n^2-1)}{2} \text{ 对不同的点对之间的最短路之和,结果对 } 998244353 \text{ 取模。}
\]
比较 hard 的题目,我们先有一个普遍的想法,看每一个特殊的四元组能有多少贡献,然后我们就会发现这个东西的情况很多,没法容斥。
接着,我们在考虑暴力的时候会想到对于每个点对暴力求答案。所以我们中和一下,先设一个 \(f_{a,b,c,d}\) 表示 \((a,b)\to (c,d)\) 的最多经过的四元组个数,发现答案是普遍贡献减掉 \(f_{a,b,c,d}\) 。
前面的答案是好求的,用等差数列求就可以了,答案是 \(\frac{n^3(n^2-1)}{3}\).然后我们呢为了减少计算量,我们发现假如用四元组的点来做网格图,每个格子的在相同终点下最多经过的四元组个数都是一样的,很方便计算。
我们先对四元组之间做一个 dp,\(dp_{i,j}\) 表示从四元组 \(i\) 到 \(j\) 的最大能经过多少四元组。这个用 floyd 求就可以了。
那我们来求这个玩意。先设一个 \(g_{x,y,i}\) 表示从格子 \((x,y)\) 出发到 \(i\) 号四元组的终点最多能经过多少四元组。我们发现这个东西可以从相邻格子和 \(dp_{i,j}\) 转移就可以了。
接下来是最难的,我们要怎么计算贡献。首先发现 \(\large f_{a,b,\text{对应i的斜侧区间}}\ge g_{Xa,Yb,i}\),然后我们就考虑差分思想。我们枚举 \(x,y\) 然后枚举 \(g\) 所在答案矩形面积并就可以,具体来说我们排序然后跑指针相加即可。这是$ O(n^4)$ ,的,注意到我们枚举重了,所以我们存一下答案,枚举 \(x,y\) 时按照答案递增的方向枚举即可 \(O(n^3)\)。
\[\text{给定一棵 } n \text{ 个节点的无根树,每条边有黑白两种颜色,初始时所有边都是黑色的。有两种操作:} \\
1. \text{操作 } 1\ u\ v: \text{将 } u \text{ 到 } v \text{ 的简单路径上的所有边颜色反转(黑变白,白变黑)。} \\
2. \text{操作 } 2\ x: \text{查询从 } x \text{ 出发,只经过黑色边能到达的点的数量(包括 } x \text{ 自身)。} \\
\text{要求处理这些操作。}
\]
这道题难在维护值,我们看一下怎么搞。首先正解从部分来,思考链上答案怎么求,很明显维护每个点的最左最右第一个白的点即可,线段树/平衡树后可以做。
跳到树上显然要树链剖分对吧,我们看一下怎么维护这个东西。有一个经典的 trick,我们对于每个点维护其轻儿子的可以到达的和,那么我们只需要跳到查询点最上方的可到达的点,就又变成链上求和了。
对于修改,我们把它拆成两个到根的修改要方便一点。看下我们要维护什么,应该是单点修改颜色和轻儿子可到达的大小,我们要同时维护两种颜色的线段树才好翻转,这个打 tag,就可以区间修改了,合并答案只有区间加法和线段树二分查询边的颜色,思维上来说不是很难,但是看着就难写。