D. Eating

D. Eating

There are n slimes on a line, the i-th of which has weight wi. Slime i is able to eat another slime j if wiwj; afterwards, slime j disappears and the weight of slime i becomes wiwj.

The King of Slimes wants to run an experiment with parameter x as follows:

  • Add a new slime with weight x to the right end of the line (after the n-th slime).
  • This new slime eats the slime to its left if it is able to, and then takes its place (moves one place to the left). It will continue to do this until there is either no slime to its left or the weight of the slime to its left is greater than its own weight. (No other slimes are eaten during this process.)
  • The score of this experiment is the total number of slimes eaten.

The King of Slimes is going to ask you q queries. In each query, you will be given an integer x, and you need to determine the score of the experiment with parameter x.

Note that the King does not want you to actually perform each experiment; his slimes would die, which is not ideal. He is only asking what the hypothetical score is; in other words, the queries are not persistent.

Here denotes the bitwise XOR operation.

Input

The first line contains an integer t (1t104) — the number of test cases.

The first line of each test case contains integers n and q (1n,q2105) — the number of slimes and the number of queries, respectively.

The following line contains n integers w1,w2,,wn (1wi<230) — the weights of the slimes.

The following q lines contain a single integer x (1x<230) — the parameter for the experiment.

The sum of n does not exceed 2105 and the sum of q does not exceed 2105 across all test cases.

Output

For each query, output a single integer — the score of the experiment.

Example

Input

3
1 1
5
6
4 4
1 5 4 11
8
13
16
15
10 9
10 4 3 9 7 4 6 1 9 4
2
6
5
6
9
8
6
2
7

Output

1
0 2 4 2
0 1 1 1 3 3 1 0 1

Note

For the first query of the second testcase:

  • A slime of weight 8 would be added to the end, so w=[1,5,4,11,8].
  • The added slime has smaller weight than the slime to its left so it cannot eat it, and thus ends the process after eating no slimes with score 0.

For the second query of the second testcase:

  • A slime of weight 13 would be added to the end, so w=[1,5,4,11,13].
  • The added slime has bigger weight than the slime to its left, and so it will eat it. Its weight will become 1311=6. Now w=[1,5,4,6].
  • The added slime will now eat the slime to its left, and its weight becomes 64=2. Now w=[1,5,2].
  • The added slime is no longer able to eat the slime to its left, so it ends the process with a score of 2.

 

解题思路

  开始一直想着找到最小的 l 使得对于每个 lin 满足 xsnsiai,结果做不出来。实际上只要注意到当 ai>x 时,必然存在一个最高的二进制位 ai1x0

  为此我们只需关注 x 的最高有效位即可。假设 x 的最高有效位是第 k 位,如果所有的 ai 的最高有效位都严格小于 k,那么一定是可以吃掉所有的 ai。如果存在存在某个 ai 的最高有效位严格大于 k,那么 ai 及其前面的都一定吃不到。而如果某个 ai 的最高有效位恰好等于 k,只有满足 aix 才能吃掉,并且 x 的最高有效位在异或了 ai 后将变小,且在之后的过程中第 k 位永远不会变成 1。意味着在整个过程中,x 的最高有效位是不断变小的,且最多变化 O(logA) 次。

  先预处理一个数组 li,j 表示第 j 个位置左边第一个最高有效位大于等于 i 的元素位置,si 表示前缀的异或和即 a1ai。定义 t 表示当前所在的位置(还没吃掉 at),初始时 t=n。整个过程就是能吃就吃。

  1. 判断是否满足 atx,如果不满足则结束整个过程。
  2. 吃掉 at,有 xxattt1
  3. 假设 x 的最高有效位为 k=logx,那么左边第一个最高有效位大于等于 k 的元素位置就是 lk,t,那么吃掉 alk,t+1at,并更新 xstslk,ttlk,t
  4. 如果 x=0 或者 t=0 则结束整个过程,否则回到第 1 步。

  最后能吃到的数量就是 nt

  AC 代码如下,时间复杂度为 O((n+q)logA)

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

typedef long long LL;

const int N = 2e5 + 5;

int a[N];
int l[30][N], s[N];

void solve() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 0; i < 30; i++) {
        for (int j = 1; j <= n; j++) {
            if (__lg(a[j]) >= i) l[i][j] = j;
            else l[i][j] = l[i][j - 1];
        }
    }
    for (int i = 1; i <= n; i++) {
        s[i] = s[i - 1] ^ a[i];
    }
    while (m--) {
        int x;
        cin >> x;
        int ret = 0, t = n;
        while (x && t) {
            if (a[t] > x) break;
            if (!(x ^ a[t])) {
                ret++;
                break;
            }
            int k = l[__lg(x ^ a[t])][t - 1];
            ret += t - k;
            x ^= s[t] ^ s[k];
            t = k;
        }
        cout << ret << ' ';
    }
    cout << '\n';
}

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

 

参考资料

  Codeforces Round 1005 (Div. 2) Editorial:https://codeforces.com/blog/entry/138912

posted @   onlyblues  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2024-02-18 F - Breakdown
2023-02-18 D. Triangle Coloring
2023-02-18 约数之和
2022-02-18 地宫取宝
Web Analytics
点击右上角即可分享
微信分享提示