T1. 城堡镇

注意到 \(x, y\) 两个轴互不影响,然后要最小化 \(\sum\limits_{i=1}^n |x-x_i|\),显然就是找中位数。如果 \(n\) 是奇数那么就能确定到唯一的一个点,如果 \(n\) 是偶数那就是一个矩形,边长是两个中位数的差。

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

void solve() {
    int n;
    cin >> n;
    
    vector<int> x(n), y(n);
    rep(i, n) cin >> x[i] >> y[i];
    
    sort(x.begin(), x.end());
    sort(y.begin(), y.end());
    
    ll ans = ll(x[n/2]-x[(n-1)/2]+1)*(y[n/2]-y[(n-1)/2]+1);
    cout << ans << '\n';
}

int main() {
    int t;
    cin >> t;
    
    while (t--) solve();
    
    return 0;
}

T2. 亲友团

\(a_i \bmod m\) 不一定是 \(0\),这个性质非常坏。所以我们先做差分。这样如果 \(a_i \bmod m = a_{i+1} \bmod m = a_{i+2} \bmod m\) 就有 \((a_{i+1} - a_i) \bmod m = (a_{i+2}-a_{i+1}) \bmod m = 0\) 了。

那么我们做完差分数组之后,记这个差分数组为 \(d_i\),如果 \(\gcd(d_{[l \cdots r-1]}) > 1\),那么 \(a_{[l \cdots r]}\) 一定是一个亲友团。

然后 \(\gcd\) 是单调递减的,所以可以双指针优化。需要用数据结构维护静态区间 \(\gcd\)

T3. 造数据

注意到限制是成链状的。如果 \(a, b\) 不存在 \(k^p\) 的倍数关系,那么 \(a\) 选不选不影响 \(b\) 选不选。

那么我们只需要对每一条链考虑。注意到这个链长度是 \(\log n\) 级别的,限制形如“链上相邻的点和相隔距离为 \(p\) 的点不能同时被选”,那么直接状压就能完成一条链的计算。

又注意到链的结构类似,所以贡献取决于长度。我们计算出每种长度链的贡献,再计算每种长度的链出现了多少次,这样就能快速计算贡献。

T4. 质因子

首先考虑一个朴素 \(dp\)

定义 \(c(x, y)\)\(\frac{x}{y}\) 的质因子次数之和。即将 \(x\) 变为 \(y\) 需要进行的操作次数。

然后设 \(f(i, j)\) 为使得 \(a_1 \leqslant a_2 \leqslant \cdots \leqslant a_i\)\(a_i = j\) 的最少步数。那么显然有转移

\[f(i, j) = c(a_i, j) + \min_{1 \leqslant k \leqslant j} f(i-1, k) \]

注意到,事实上我们只需要考虑 \(j\)\(a_i\) 的约数的情况。由于 \(5e5\) 以内数的约数个数均 \(\leqslant 200\),所以这样我们至多只需要考虑 \(200n\) 个状态。

由于转移只与 \(f(i-1, *)\) 的前缀最小值有关,所以我们可以先预处理出每个数的所有约数,然后用双指针转移。

总复杂度为 \(\mathcal{O}(m\log m + nd)\),其中 \(d \leqslant 200\)