想用博客记录一下自己做到的好题,希望对以后的自己和大家有帮助

Codeforces Round 1016 Div.3 G

题目大意

在长度为 \(n\) 的数组, 价值为 \(f = max(b_{l} \oplus b_{r})\) , 如果数组价值大于 \(k\), 那么我们称其为美丽的
现在要在原数组中寻找最短的连续子数组, 且满足\(f \ge k\)

input

组数 \(t\)
接下来 $ 2 * t$ 行:
\(~~~\)数组长度 \(n\)
\(~~~\)\(n\) 个整数 \(a_{1...n}\)

output

最短长度 \(l\) , 若找不到则输出 \(-1\)

题解

0-1 trie树
异或和最大, 可以用0-1trie树来维护, 除此之外我们还要额外记录一下某点满足 \(f \ge k\) 的最小长度

我们从左往右依次向trie树中插入 \(a_i\) , 同时查询满足 $a_j \oplus a_i \ge k $ 的最大下标 \(j\), 同时维护最小值 \(minn\)

有点像数位dp的思路, 我们把 $a_j \oplus a_i \ge k $ 拆成两部分, $a_j \oplus a_i > k $ 与 $a_j \oplus a_i = k $, 于是有接下来的分类讨论

从高到底枚举k的位数

  1. 如果二级制的 \(k\) 中第 \(t\) 位为 1 , 我们必须沿着 1 走下去
  2. 反之为 0 , 如果存在 1 的道路, 我们查询最大的能到达 1 的下标, 此时为 $a_j \oplus a_i > k $; 但我们仍要按照 0 继续向下走, 去判断 $a_j \oplus a_i = k $ 的情况
  3. 如果成功走到底, 特判一下 $a_j \oplus a_i = k $

code

vector维护trie树

 struct Node
{
    int chl[2] = {0, 0};
    int last;//存最后一次到达该点的下标
};
void solve()
{
    idx = 0; vector<Node> tr(1);
    int minn = INF;
    scanf("%d%d", &n, &k);
    for(int i = 1; i <= n; i++)
    {
        int a; scanf("%d", &a);
        if(k == 0) minn = 0;
        int u = insert(tr, a, i);
        if(u != -1)
            minn = min(i - u, minn);
    }
    if(minn != INF)
        printf("%d\n", minn + 1);
    else puts("-1");
}

因为有 \(t\) 组输入, 如果用数组模拟的话需要每次清零, 耗费大量时间和空间

int insert(vector<Node> &tr, int s, int t)
{
    int p = 0, maxx = -1, q = 0;
    tr[p].last = max(tr[p].last, t);
    for(int i = 29; i >= 0; i--)
    {
        int u = s >> i & 1;
        int v = k >> i & 1;

        if(q != -1 && v == 0 && tr[q].chl[u ^ 1]) maxx = max(maxx, tr[tr[q].chl[u ^ 1]].last);// ">" 的情况
        if(q != -1 && tr[q].chl[u ^ v]) q = tr[q].chl[u ^ v];
        else q = -1;

        tr[p].last = max(tr[p].last, t);
        if(!tr[p].chl[u]) 
        {
            tr[p].chl[u] = tr.size();
            tr.push_back(Node());
        }
        p = tr[p].chl[u];
    }
    if(q != -1) maxx = max(maxx, tr[q].last); // "=" 的情况
    tr[p].last = max(tr[p].last, t);
    return maxx;
}
posted on 2025-04-10 17:28  LHWYAN  阅读(58)  评论(0)    收藏  举报