zoukankan      html  css  js  c++  java
  • CF1444B(CF1445D) Divide and Sum

    一个水题,但是考场上愣是想了一个小时,最后忘了加模数再取模导致我fst。

    考虑 (mid x_i - y_i mid) 的意义,就是 (max(x_i, y_i) - min(x_i, y_i)) 那么就是说对于每个位置,取两个排列中的最大值减去最小值。

    这样的排列一共会有 (C_{2n}^n) 个。

    这里先给出一个结论,排序后,后半部分永远会被取成最大值,前半部分永远会被取成最小值。

    (以下内容均以排序后的原数组为准)

    上述结论是由其排列排列顺序决定的,考虑后半部分的数如果放到 (p) 中,那么一定在最后几个。如果放到 (q) 中,一定在前几个,那么我们可以知道原序列的一半恰好等于 (p, q) 的长度,那么其实这些元素是不会相互之见取最大最小值的。

    所以答案即为排序后的数组 (displaystyle Big( sum_{i=n+1}^{2cdot n} a_i - sum_{i=1}^n a_i Big) cdot C_{2n}^n)

    我比较菜,写的线性求逆元+阶乘。

    时间复杂度 (O(n)),空间复杂度 (O(n))

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    
    using namespace std;
    
    typedef long long ll;
    const ll MAXN = 1e6+10, MOD = 998244353;
    
    ll N, M, fac[MAXN], val[MAXN], inv[MAXN], ans;
    
    int main() {
        scanf("%lld", &N);
        inv[1] = inv[0] = fac[1] = fac[0] = 1;
        for (ll i = 2; i <= N<<1; i++) fac[i] = fac[i-1] * i % MOD, inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
        for (ll i = 1; i <= N<<1; i++) inv[i] = inv[i-1] * inv[i] % MOD;
        for (ll i = 1; i <= N<<1; i++)
            scanf("%lld", val+i);
        ll tem = fac[N<<1] * inv[N] % MOD * inv[N] % MOD;
        sort(val+1, val+(N<<1)+1);
        for (ll i = 1; i <= N; i++)
            ans = (ans - tem * val[i] % MOD) % MOD;
        for (ll i = N + 1, k = N << 1; i <= k; i++)
            ans = (ans + tem * val[i] % MOD) % MOD;
        printf("%lld
    ", (ans + MOD) % MOD);
        return 0;
    }
    
  • 相关阅读:
    signals系列之一——基本用法
    libevent系列之一——libevent介绍
    memcached完全剖析系列——一、memcached基础
    分布式算法一——一致性hash算法
    spring容器启动过程
    dubbo源码之四——服务发布二
    dubbo源码之四——dubbo服务发布
    dubbo源码之三——dubbo重构
    dubbo源码之三-模块依赖
    [模板](luogu P3387)縮點
  • 原文地址:https://www.cnblogs.com/Gensokyo-Alice/p/13911997.html
Copyright © 2011-2022 走看看