• 第十三届蓝桥杯JavaA组、C++A组省赛 J 题——推导部分和 (AC)


    1.推导部分和

    1.题目描述

    对于一个长度为 N N N 的整数数列 A 1 , A 2 , ⋯ A N A_{1}, A_{2}, \cdots A_{N} A1,A2,AN , 小蓝想知道下标 l l l r r r 的部分和 ∑ i = l r = A l + A l + 1 + ⋯ + A r \sum_{i=l}^{r}=A_{l}+A_{l+1}+\cdots+A_{r} i=lr=Al+Al+1++Ar是多少?

    然而, 小蓝并不知道数列中每个数的值是多少, 他只知道它的 M M M 个部分和 的值。
    其中第 i i i 个部分和是下标 l i l_{i} li r i r_{i} ri 的部分和 ∑ j = l i r i = A l i + A l i + 1 + ⋯ + A r i \sum_{j=l_{i}}^{r_{i}}=A_{l_{i}}+A_{l_{i}+1}+\cdots+A_{r_{i}} j=liri=Ali+Ali+1++Ari, 值是 S i S_{i} Si

    2.输入格式

    第一行包含 3 个整数 N 、 M N 、 M NM Q Q Q 。分别代表数组长度、已知的部分和数量 和询问的部分和数量。

    接下来 M M M 行, 每行包含 3 个整数 l i , r i , S i l_{i}, r_{i}, S_{i} li,ri,Si 。接下来 Q Q Q 行, 每行包含 2 个整数 l l l r r r, 代表一个小蓝想知道的部分和。

    3.输入格式

    对于每个询问, 输出一行包含一个整数表示答案。如果答案无法确定, 输出 UNKNOWN。

    4.样例输入

    5 3 3
    1 5 15
    4 5 9
    2 3 5
    1 5
    1 3
    1 2

    5.样例输出

    15
    6
    UNKNOWN

    6.数据范围

    对于所有评测用例, 1 ≤ N , M , Q ≤ 1 0 5 , − 1 0 12 ≤ S i ≤ 1 0 12 , 1 ≤ l i ≤ r i ≤ N , 1 ≤ l ≤ r ≤ N , 1 \leq N, M, Q \leq 10^{5},-10^{12} \leq S_{i} \leq 10^{12}, 1 \leq l_{i} \leq r_{i} \leq N,1≤ l ≤ r ≤ N, 1N,M,Q105,1012Si1012,1liriN1lrN, 。数据保证没有矛盾。

    7.原题链接

    推导部分和

    2.解题思路

      首先先考虑我们平时在前缀和数组中如何求解一段区间 [ l , r ] [l,r] [l,r]的和,我们一般是写为 s [ r ] − s [ l − 1 ] s[r]-s[l-1] s[r]s[l1]。如果已知区间 [ l , r ] [l,r] [l,r] 的和,这意味着我们可以从 l − 1 l-1 l1 跳转到 r r r
    在这里插入图片描述
      如图,假设给定区间 [ 2 , 4 ] [2,4] [2,4] [ 5 , 7 ] [5,7] [5,7]的和,很明显两个区间结合起来我们可以得到 [ 2 , 7 ] [2,7] [2,7]的和。我们一段已知区间 [ l , r ] [l,r] [l,r],我们将 l − 1 l-1 l1 r r r 连通起来,如图红线。可知 1 、 4 、 7 1、4、7 147处于一个连通分量,这意味着我们可以通过 s [ 7 ] − s [ 4 ] s[7]-s[4] s[7]s[4]来得到区间 [ 5 , 7 ] [5,7] [5,7]的和以及 s [ 4 ] − s [ 1 ] s[4]-s[1] s[4]s[1]来得到 [ 2 , 4 ] [2,4] [2,4]的和,最主要的是可以通过 s [ 7 ] − s [ 1 ] s[7]-s[1] s[7]s[1]来得到 [ 2 , 7 ] [2,7] [2,7]的和,由此可以产生合并效果。

      维护连通分量我们理所应当使用并查集来维护,当求解区间 [ l , r ] [l,r] [l,r]的值时,我们只需要判断 l − 1 l-1 l1 r r r 是否属于同一个连通分量即可,如果不是则说明无解输出UNKNOWN。当然题目需要我们输出具体的区间和而不是判断是否能求解出,所以朴素的并查集并无法满足我们的要求,我们需要使用带权并查集

      不熟悉带权并查集的同学请回顾前文:带权并查集

      我们同样来维护到头结点的距离,而头结点应当是每个联通分量最右端的点,如果上图点 4 到 点 7 的距离就是 [ 5 , 7 ] [5,7] [5,7] 区间和,而点 1 到 点 4 的距离同理可维护。因为 7 才应该是头结点,所以 17 的距离应当是 14 加上 47,这在并查集路径压缩中可实现。求解区间 [ l , r ] [l,r] [l,r] 时,只需要用 d [ r ] − d [ l − 1 ] d[r]-d[l-1] d[r]d[l1] 即可,d[]则是维护联通分量中到头结点的距离,具体细节见代码。

    3.Ac_code

    #include
    using namespace std;
    typedef long long LL;
    typedef unsigned long long uLL;
    typedef pair<int, int> PII;
    #define pb(s) push_back(s);
    #define SZ(s) (int)s.size();
    #define ms(s,x) memset(s, x, sizeof(s))
    #define all(s) s.begin(),s.end()
    const int inf = 0x3f3f3f3f;
    const int mod = 1000000007;
    const int N = 200010;
    
    struct UF {
        std::vector<LL> f, d;
        UF(int n) : f(n), d(n, 0) { std::iota(f.begin(), f.end(), 0); }
        int find(int x) {
            if (x == f[x]) return x;
            //先记录祖宗
            int root = find(f[x]);
            //加上父亲的距离
            d[x] += d[f[x]];
            return f[x] = root;
        }
        bool same(int x, int y) { return find(x) == find(y); }
        bool merge(int u, int v, LL w) {
            int x = find(u);
            int y = find(v);
            if (x == y) return false;
            f[x] = y;
            d[x] = w + d[v] - d[u];
            return true;
        }
    };
    int n, m, q;
    LL s;
    void solve()
    {
        cin >> n >> m >> q;
        UF uf(n + 10);
        for (int i = 1; i <= m; ++i)
        {
            LL l, r , s;
            cin >> l >> r >> s;
            uf.merge(l - 1, r , s);
        }
        for (int i = 1; i <= q; ++i)
        {
            int l, r;
            cin>>l>>r;
            if (!uf.same(l - 1, r)) cout << "UNKNOWN" << '\n';
            else cout << uf.d[l - 1] - uf.d[r] << '\n';
        }
    }
    int main()
    {
        ios_base :: sync_with_stdio(false);
        cin.tie(nullptr);
        int t = 1;
        while (t--)
        {
            solve();
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
  • 相关阅读:
    【解决方案】SkeyeVSS+ SkeyeARS“国土卫士”农田水利视频监管系统,实现国土资源监管智能化
    opencv之图像翻转、平移、缩放、旋转、仿射学习笔记
    字符串拼接re.sub()用法
    k8s驱逐篇(2)-kubelet节点压力驱逐
    图解ReentrantLock底层公平锁和非公平锁实现原理
    ESP8266_接入百度物联网核心套件、使用MQTT协议通信
    基于VC的WinSock网络编程实用宝典
    Spring基础(3):复习
    Python_it_heima
    【测量学】速成汇总——摘录高数帮
  • 原文地址:https://blog.csdn.net/m0_57487901/article/details/127684723