1 条题解

  • 0
    @ 2025-8-24 22:26:37

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 一扶苏一
    休息结束。邮箱 yifusuyi@qq.com

    搬运于2025-08-24 22:26:37,当前版本为作者最后更新于2020-11-22 12:04:56,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    F

    Algorithm 1

    对于虫洞间距离不超过 22 的情况,显然答案只有 0011 两种可能。期望得分 2020 分。

    Algorithm 2

    考虑推一推式子。设 fif_i 表示在坐标 ii 时的期望步数,那么转移显然:

    fi=12(fi1+fi+1)+1f_{i} = \frac 1 2(f_{i - 1} + f_{i + 1}) + 1

    这个式子的意思是分别有 12\frac 1 2 的概率向左走向右走,然后变为对应坐标的期望步数。同时因为走了一步,所以最后要 +1+1

    边界条件是在虫洞结点上 fi=0f_i = 0

    对于子任务 33,可以通过手算发现这时候不在虫洞上的 ff 的值为 22。结合算法一,期望得分 3030 分。

    Algorithm 3

    用高斯消元求解算法二中的式子,时间复杂度 O(qn3)O(qn^3),期望得分 5050 分。

    Algorithm 4

    验题人拉瓦手算带入消元得到了一个递推式,可以矩阵加速,时间复杂度 O(qlogn)O(q \log n)88 倍常数。期望得分 7070 分。

    Algorithm 5

    考虑把算法二中的式子乘二然后整理,可以得到

    (fi+1fi)(fifi1)=2(f_{i + 1} - f_{i}) - (f_{i} - f_{i - 1}) = -2

    这就是说,ff 的二阶差分是一个非零常数。因此 ff 的通项公式一定是一个二次多项式。

    我们考虑正着推式子:对于 g(x)=ax2+bx+cg(x) = ax^2 + bx + c,有 g(x1)=a(x22x+1)+b(x1)+cg(x - 1) = a(x^2 - 2x + 1) +b(x - 1) + cg(x+1)=a(x2+2x+1)+b(x+1)+cg(x + 1) = a(x^2 + 2x + 1) +b(x + 1) + c

    因此 g(x)g(x1)=2axa+bg(x) - g(x - 1) = 2ax - a + bg(x+1)g(x)=2ax+a+bg(x + 1) - g(x) = 2ax + a + b

    因此 [g(x+1)g(x)][g(x)g(x1)]=2a[g(x + 1) - g(x)] - [g(x) - g(x - 1)] = 2a。这就是说,二次函数的二阶差分值是其二次项系数的两倍。因此可以得到 ff 的通项公式的二次项系数是 1-1。同时我们还知道 ff 的两个零点,因此可以直接以零点式写出 ff 的通项公式,带入 xx 即可 O(1)O(1) 计算。时间复杂度 O(nlogn+q)O(n \log n + q)。这里的 logn\log n 需要对 xx 数组进行排序。然后用指针指向第一个大于询问值的元素。因为询问是单调不降的,所以指针移动是均摊 O(1)O(1) 的。期望得分 100100 分。

    #include <cstdio>
    #include <cctype>
    #include <iostream>
    #include <algorithm>
    
    template <typename T>
    inline void qr(T &x) {
      char ch = getchar(); x = 0;
      while (!isdigit(ch)) ch = getchar();
      while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
    }
    
    const int maxn = 100005;
    const int mod = 998244353;
    
    
    int n, q;
    int ans, answ, answe = -1, answer = mod + 1; 
    int a[maxn];
    
    int main() {
      qr(n); qr(n); qr(q);
      for (int i = 1; i <= n; ++i) {
        qr(a[i]);
      }
      std::sort(a + 1, a + 1 + n);
      for (int x, p = 1; q; --q) {
        qr(x);
        while ((p < n) && (a[p] <= x)) ++p;
        int y = 1ll * (x - a[p - 1]) * (a[p] - x) % mod;
        ans ^= y;
        if (y & 1) ++answ;
        answe = std::max(answe, y);
        answer = std::min(answer, y);
      }
      std::cout << ans << std::endl << answ << std::endl << answe << std::endl << answer << std::endl;
    }
    
    • 1

    信息

    ID
    6272
    时间
    1000ms
    内存
    500MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者