CF840E In a Trap

CF840E In a Trap

这题似乎挺经典的。给类似的位运算维护提供了一个思路。

初看题,这个形式很明显是把树上路径拆分成了若干段,这个询问很奇怪。

智商不够阈值分治来凑。每个点向上预处理 \(256\) 的长度的信息,这样就只需考虑高位带来的影响了。那么需要预处理的就是 \(f_{u,k}\) 表示这条链中异或上 \(256k\) 的最大值。这个是方便用 Trie 维护的。

于是就做完了。询问直接跳链查询就行了。

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

namespace IO {
#define isdigit(x) (x >= '0' && x <= '9')
template<typename T>
  inline void read(T &x) {
  x = 0; char ch = getchar(); int f = 0;
  for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
  for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - '0';
  if(f) x = -x;
}
template<typename T, typename... Rest>
inline void read(T &x, Rest&... rest) {
   read(x), read(rest...);
}
template<typename T>
inline void write(T x) {
  if(x < 0) putchar('-'), x = -x;
  if(x > 9) write(x / 10);
  putchar(x % 10 + '0');
}
#undef isdigit
}
using namespace IO;

const int N = 50010;
const int B = 266;
int n, q, a[N], dep[N];
vector<int> G[N];
int adj[N][B], nxt[N];
int f[N][B];

void dfs(int u, int fa) {
  dep[u] = dep[fa] + 1;
  for(int v : G[u]) {
    if(v == fa) continue;
    adj[v][0] = v;
    for(int i = 1; i <= 255; ++i)
      adj[v][i] = adj[u][i - 1];
    nxt[v] = adj[u][255];
    dfs(v, u);
  }
}

struct Trie {
  int tot, tr[N][2];
  
  void clear() {
    for(int i = 1; i <= tot; ++i)
      tr[i][0] = tr[i][1] = 0;
    tot = 1;
  }
  
  void insert(int x) {
    int u = 1;
    for(int i = 15; ~i; --i) {
      int tp = x >> i & 1;
      if(!tr[u][tp]) tr[u][tp] = ++tot;
      u = tr[u][tp];
    }
  }

  int query(int x) {
    int u = 1, res = 0;
    for(int i = 15; ~i; --i) {
      int tp = (x >> i & 1) ^ 1;
      if(tr[u][tp]) u = tr[u][tp], res |= 1 << i;
      else u = tr[u][tp ^ 1];
    }
    return res;
  }
}trie;

void solve()  {
  int u, v, ans = 0, k = 0;
  read(u, v);
  while(dep[nxt[v]] >= dep[u]) {
    ans = max(ans, f[v][k]);
    ++k, v = nxt[v];
  }
  int step = k << 8;
  while(v != u) {
    ans = max(ans, a[v] ^ step);
    v = adj[v][1], ++step;
  }
  ans = max(ans, a[u] ^ step);
  printf("%d\n",ans); 
}

int main() {
  read(n, q);
  for(int i = 1; i <= n; ++i)
    read(a[i]);
  for(int i = 1; i < n; ++i) {
    int u, v;
    read(u, v);
    G[u].emplace_back(v);
    G[v].emplace_back(u);
  }
  
  adj[1][0] = 1;
  dfs(1, 0);

  for(int i = 1; i <= n; ++i) {
    trie.clear();
    for(int j = 0; j <= 255; ++j) {
      int x = adj[i][j];
      if(!x) break;
      trie.insert(a[x] ^ j);
    }
    for(int j = 0; j <= 255; ++j) 
      f[i][j] = trie.query(j << 8);
  }

  while(q--) solve();
  return 0;
}
posted @ 2023-05-18 17:31  DCH233  阅读(16)  评论(0编辑  收藏  举报