「解题报告」ARC126F Affine Sort

目前为止在 ARC 做到过的最震撼的数学题。

我们先把 \(f(K)\) 改写一下,设 \(g(K)\) 表示当 \(c=K\) 时合法的 \((a, b)\) 二元组数,那么就有:

\[f(K) = \sum_{i=0}^K g(i) \]

那么根据 O'Stolz 定理 我们要求的式子为:

\[\lim_{K \to \infty} \frac{f(K)}{K^3} = \lim_{K \to \infty} \frac{g(K)}{3K^2} = \frac{1}{3}\lim_{K \to \infty} \frac{g(K)}{K^2} \]

O'Stolz 定理
简单来说就是洛必达法则的离散版本,可以用于求数列极限。
假如有数列 \(\{a_n\}, \{b_n\}\) 满足:

  1. \(\{b_n\}\) 严格单调递增;
  2. \(\lim_{n \to \infty} b_n = +\infty\)

那么有:

\[\lim_{n\to \infty} \frac{a_n}{b_n} = \lim_{n \to \infty} \frac{a_{n + 1} - a_n}{b_{n + 1} - b_n} \]

那么接下来我们只需要求出 \(\lim_{K \to \infty}\frac{g(K)}{K^2}\) 即可。

我们不妨把问题转换一下:

\[aX_i + b \bmod K \to \frac{a}{K}X_i + \frac{b}{K} \bmod 1 \]

而由于 \(K \to \infty\),那么我们可以理解为 \(\frac{a}{K}, \frac{b}{K}\) 取遍 \([0, 1]\) 内的所有实数。

那么假如设 \(\alpha = \frac{a}{K}, \beta = \frac{b}{K}\),并且将所有合法的 \((\alpha, \beta)\) 看做一个二维平面上的一个大小为 \(\frac{1}{K^2}\) 的区域,那么我们要求的 \(\frac{g(K)}{K^2}\) 就是求这个二维平面的面积。当 \(K \to \infty\) 时,我们就可以把每一个 \(\frac{1}{K^2}\) 的面积近似的看做一个点,那么现在我们相当于就是求这个二维平面上的积分了。实际上,根据测度论的相关知识,可以证明两者的极限是相等的。

image

那么我们现在就把 \(\alpha, \beta\) 看做是 \([0, 1]\) 上的实数来考虑这个问题。

我们设 \(\{x\}\)\(x\) 的小数部分,即 \(x \bmod 1 = x - \lfloor x\rfloor\)

对于\(\bmod 1\) 的问题,我们可以将其放到一个环上来考虑,然后将每个数看做环上的点。那么我们发现,\(\beta\) 的作用就是将整个环旋转了若干位置。假如此时 \(\{\alpha X_i\}\) 从某一位置开始是有序的,那么我们就可以通过一些旋转使得他们从 \(0\) 开始是有序的。这相当于将 \(0\) 的位置旋转到 \(\{\alpha X_1\}\)\(\{\alpha X_n\}\) 之间,那么对于某一个固定的 \(\alpha\),合法的 \(\beta\) 的积分为 \(\{\alpha(X_1-X_n)\}\)

image

那么我们如何确定对于哪些 \(\alpha\) 来说,\(\{\alpha X_i\}\) 从某一位置开始是有序的呢?我们可以使用距离之和来刻画这件事情。设 \(d_k(\alpha) = \{\alpha(X_{k \bmod n + 1} - X_k)\}\),那么有序当且仅当 \(D(\alpha)=\sum_{k=1}^n d_k(\alpha) = 1\)

那么我们考虑 \(D(\alpha)\) 在哪里取到 \(1\),对这些 \(\alpha\) 计算上述的 \(\beta\) 的积分即可。

同时,我们注意到斜率 \(\sum_{i=1}^n (X_{k \bmod n + 1} - X_k) = 0\),也就是说 \(D(\alpha)\) 的图像为若干条横着的直线组成的,那么如果我们找出所有 \(y=1\) 的直线的区域,对这些区域进行积分,就能计算出答案了。

我们先考虑一个单独的函数 \(f(x) = \{kx\}\) 长什么样子。发现这就是一个一次函数,并在有限个位置进行了 \(\pm 1\) 的值的变化。

image

而我们发现,这样的变化的位置的数量是 \(O(\sum X_i)\) 的,那么我们就可以暴力维护出所有这样的点,这样就能维护出 \(D(\alpha)\) 的图像了。找到图像之后,对每一段 \(y=1\) 的位置求 \(\int_{l}^r \{\alpha(X_1 - X_n)\}\)。这个积分同样可以从间断点断开,求若干个一次函数的积分即可。

代码贺的。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1005, P = 998244353;
int qpow(int a, int b) {
    int ans = 1;
    while (b) {
        if (b & 1) ans = 1ll * ans * a % P;
        a = 1ll * a * a % P;
        b >>= 1;
    }
    return ans;
}
int n, x[MAXN];
struct Fraction {
    int a, b;
    Fraction(int x = 0, int y = 1) : a(x), b(y) {
        int g = __gcd(a, b);
        a /= g, b /= g;
    }
    bool operator<(const Fraction &x) const {
        return 1ll * a * x.b < 1ll * b * x.a;
    }
    bool operator<=(const Fraction &x) const {
        return !(x < *this);
    }
    operator int() {
        return 1ll * a * qpow(b, P - 2) % P;
    }
};
map<Fraction, int> mp;
int integral(int k, int b, int l, int r) {
    k = (k % P + P) % P;
    b = (b % P + P) % P;
    return (
        (P + 1ll) / 2 * k % P * r % P * r % P + 1ll * b * r % P - 
        (P + 1ll) / 2 * k % P * l % P * l % P - 1ll * b * l % P + 2 * P
    ) % P;
}
int main() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &x[i]);
    }
    x[n + 1] = x[1];
    for (int i = 1; i <= n; i++) {
        if (x[i] < x[i + 1]) {
            for (int j = 1; j < x[i + 1] - x[i]; j++) {
                mp[{j, x[i + 1] - x[i]}]--;
            }
        } else {
            for (int j = 0; j < x[i] - x[i + 1]; j++) {
                mp[{j, x[i] - x[i + 1]}]++;
            }
        }
    }
    mp[{0, 1}], mp[{1, 1}];
    int y = 0, b = 0;
    int ans = 0;
    vector<pair<Fraction, int>> v;
    for (auto p : mp) {
        v.push_back(p);
    }
    for (int i = 0; i + 1 < v.size(); i++) {
        y += v[i].second;
        while (Fraction(b + 1, abs(x[1] - x[n])) <= v[i].first) b++;
        if (y == 1) {
            ans = (ans + integral(x[1] - x[n], x[1] > x[n] ? -b : b + 1, v[i].first, v[i + 1].first)) % P;
        }
    }
    ans = 1ll * ans * qpow(3, P - 2) % P;
    printf("%d\n", ans);
    return 0;
}
posted @ 2023-03-26 09:34  APJifengc  阅读(51)  评论(2编辑  收藏  举报