D. Array Repetition

D. Array Repetition

Jayden has an array $a$ which is initially empty. There are $n$ operations of two types he must perform in the given order.

  1. Jayden appends an integer $x$ ($1 \leq x \leq n$) to the end of array $a$.
  2. Jayden appends $x$ copies of array $a$ to the end of array $a$. In other words, array $a$ becomes $[a,\underbrace{a,\ldots,a}_{x}]$. It is guaranteed that he has done at least one operation of the first type before this.

Jayden has $q$ queries. For each query, you must tell him the $k$-th element of array $a$. The elements of the array are numbered from $1$.

Input

Each test consists of multiple test cases. The first line contains a single integer $t$ ($1 \leq t \leq 5000$) — the number of test cases. The description of the test cases follows.

The first line of each test case contains two integers $n$ and $q$ ($1 \leq n, q \leq 10^5$) — the number of operations and the number of queries.

The following $n$ lines describe the operations. Each line contains two integers $b$ and $x$ ($b \in \{1, 2\}$), where $b$ denotes the type of operation. If $b=1$, then $x$ ($1 \leq x \leq n$) is the integer Jayden appends to the end of the array. If $b=2$, then $x$ ($1 \leq x \leq 10^9$) is the number of copies Jayden appends to the end of the array.

The next line of each test case contains $q$ integers $k_1, k_2, \ldots, k_q$ ($1 \leq k_i \leq \min(10^{18}, c)$), which denote the queries, where $c$ is the size of the array after finishing all $n$ operations.

It is guaranteed that the sum of $n$ and the sum of $q$ over all test cases does not exceed $10^5$.

Output

For each test case, output $q$ integers — answers to Jayden's queries.

Example

input

4
5 10
1 1
1 2
2 1
1 3
2 3
1 2 3 4 5 6 14 15 16 20
10 10
1 3
1 8
2 15
1 6
1 9
1 1
2 6
1 1
2 12
2 10
32752 25178 3198 3199 2460 2461 31450 33260 9016 4996
12 5
1 6
1 11
2 392130334
1 4
2 744811750
1 10
1 5
2 209373780
2 178928984
1 3
2 658326464
2 1000000000
914576963034536490 640707385283752918 636773368365261971 584126563607944922 1000000000000000000
2 2
1 1
1 2
1 2

output

1 2 1 2 3 1 2 3 1 3
9 8 1 3 1 3 6 3 8 8
11 11 11 10 11
1 2

Note

In the first test case:

  • After the first operation $a = [1]$;
  • After the second operation $a = [1, 2]$;
  • After the third operation $a = [1, 2, 1, 2]$;
  • After the fourth operation $a = [1, 2, 1, 2, 3]$;
  • After the fifth operation $a = [1, 2, 1, 2, 3, 1, 2, 1, 2, 3, 1, 2, 1, 2, 3, 1, 2, 1, 2, 3]$.

In the fourth test case, after all operations $a = [1, 2]$.

 

解题思路

  首先我们不可能根据操作把数组 $a$ 模拟建出来,否则时间和空间复杂度都会爆掉,意味着一定是通过“压缩”的方式来存储数组 $a$ 的信息。

  考虑用链式结构依次存储每个状态 $a$ 的信息,那么每个节点存储哪些参数呢?对于操作 $2$,显然要记录拷贝前 $a$ 的大小(也就是当前 $a$ 的大小),记作 $sz$,以及拷贝后的数量 $x+1$,记作 $c$。这样对于当前节点的两个参数 $sz$ 与 $c$,就可以得知当前的 $a$ 是将前一个节点所表示的数组拷贝 $c$ 份得到的,大小为 $sz \cdot c$。

  另外对于操作 $1$,我们还需要在节点中记录数组的最后一个元素是什么,如果有连续的操作 $1$,为了避免开额外的节点我们在节点中用一个 std::vector 来记录连续的操作 $1$ 压入的元素,只有在操作 $2$ 时才开新的节点。由于询问的下标不超过 $10^{18}$ 这样做就可以保证在 $n$ 次操作后节点的数量不超过 $61$ 个(因为 $2^{61} > 10^{18}$,同时当数组 $a$ 的大小不超过 $10^{18}$ 才执行操作)。

  因此新的节点的参数 $sz$ 就是前一个节点的 $sz \cdot c + \text{size}(q)$,$\text{size}(q)$ 是std::vector 的大小。另外只有在当前数组大小不超过 $10^{18}$ 时才进行拷贝,同时还要保证拷贝后的数组大小不超过 $10^{18}$,即新节点的参数 $c$ 实际上应该是 $\min\left\{ x+1, \, \left\lceil \frac{10^{18}}{sz} \right\rceil \right\}$,这里的 $sz$ 是新节点的。

  对于询问 $x$,只需从后往前依次枚举每个节点,对于当前节点状态的数组,记 $s = sz \cdot c$,表示上一个状态的数组拷贝了 $c$ 份后的大小。如果 $x \in \left[  s + 1, \, s + \text{size}(q) \right]$,那么很明显答案就是 $q[x-s-1]$。否则 $x$ 的位置在某份拷贝的数组中(即大小为 $sz$ 的数组),令 $x \gets (x-1) \bmod sz + 1$,得到其所在拷贝的数组的下标,然后遍历到前一个节点用同样的方法继续处理。

  AC 代码如下,时间复杂度为 $O(q \cdot \log{A})$:

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

struct Node {
    LL sz, c;
    vector<int> q;
};

void solve() {
    int n, m;
    cin >> n >> m;
    vector<Node> p({{0}});
    while (n--) {
        int op, x;
        cin >> op >> x;
        if (op == 1) {
            p.back().q.push_back(x);
        }
        else {
            LL sz = p.back().sz * p.back().c + p.back().q.size();
            if (sz < (LL)1e18) p.push_back({sz, min(x + 1ll, ((LL)1e18 + sz - 1) / sz)});
        }
    }
    while (m--) {
        LL x;
        cin >> x;
        for (int i = p.size() - 1; i >= 0; i--) {
            LL sz = p[i].sz * p[i].c;
            if (x > sz) {
                cout << p[i].q[x - sz - 1] << ' ';
                break;
            }
            else {
                x = (x - 1) % p[i].sz + 1;
            }
        }
    }
    cout << '\n';
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 919 (Div. 2) 题解:https://www.cnblogs.com/zsc985246/p/17963255

  Editorial for Codeforces Round #919 (Div. 2):https://codeforces.com/blog/entry/122560

posted @ 2024-01-19 21:17  onlyblues  阅读(4)  评论(0编辑  收藏  举报
Web Analytics