1 条题解

  • 0
    @ 2026-6-19 10:30:17

    📝 题目大意

    NN 个数列,第 ii 个数列有 LiL_i 项。给定 QQ 个查询,每个查询给出行号 sks_k 和列号 tkt_k,要求输出第 sks_k 个数列的第 tkt_k 项的值。

    💡 解题思路

    1. 题目分析N,Q2×105N, Q \leq 2 \times 10^5,且 Li2×105\sum L_i \leq 2 \times 10^5,数据总量在可接受范围内。关键约束在于 Li\sum L_i 的上限,意味着所有元素的总个数不超过 2×1052 \times 10^5,因此用二维数组直接存储所有元素是可行的,不会爆内存。

    2. 算法推导

      • 使用 vector<int> a[N+1] 存储每个数列(编号 1N1 \sim N)。
      • 依次读入每个数列的长度 LiL_iLiL_i 个元素,将其 push_backa[i] 中。
      • 对于每个查询 (s,t)(s, t),直接输出 a[s][t-1](注意题目的 tt11 索引,而 vector 下标从 00 开始,因此需要减 11)。
    3. 边界与细节

      • 输入保证 tkLskt_k \leq L_{s_k},因此不会出现越界访问。
      • 元素值最大 10910^9,在 int 范围内,无需使用 long long
      • 使用 scanf/printf 保证在 2×1052 \times 10^5 级别的输入输出量下不会超时。

    ⏱️ 复杂度分析

    • 时间复杂度O(Li+Q)O\left(\sum L_i + Q\right)。读入所有元素需要 O(Li)O(\sum L_i),回答 QQ 个查询每次 O(1)O(1)
    • 空间复杂度O(Li)O\left(\sum L_i\right)。所有元素存储在 vector 中。

    💻 标准代码 (C++)

    #include <bits/stdc++.h>
    using namespace std;
    vector<int> a[200005];  // a[i] 存储第 i 个数列的所有元素
    int n, q, l, s, t, x;
    
    int main() {
        scanf("%d%d", &n, &q);
        // 读入 N 个数列
        for (int i = 1; i <= n; i++) {
            scanf("%d", &l);          // 第 i 个数列的长度
            for (int j = 1; j <= l; j++) {
                scanf("%d", &x);      // 读入每个元素
                a[i].push_back(x);    // 存入对应数列的 vector
            }
        }
        // 处理 Q 个查询
        while (q--) {
            scanf("%d%d", &s, &t);           // 查询第 s 个数列的第 t 项
            printf("%d\n", a[s][t - 1]);     // 下标从 0 开始,需要减 1
        }
        return 0;
    }
    
    • 1

    信息

    ID
    641
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者