1 条题解

  • 0
    @ 2025-8-24 22:14:27

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar kai586123
    啊嗯

    搬运于2025-08-24 22:14:27,当前版本为作者最后更新于2019-12-16 21:57:07,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    异或kk大问题当然是一位一位算啦~枚举每一位,算可能的答案中这一位有多少00有多少11就好。

    发现结果和行,列都有关,且nn很小,可以考虑枚举行,计算这一行有多少满足要求的。

    YY建一棵可持久化Trie,询问的时候每一行维护一下走到了Trie的哪里,根据0101数量决定走哪边就好了。

    #include <bits/stdc++.h>
    
    inline int rd() {
      int a = 1, b = 0; char c = getchar();
      while (!isdigit(c)) a = c == '-' ? 0 : 1, c = getchar();
      while (isdigit(c)) b = b * 10 + c - '0', c = getchar();
      return a ? b : -b;
    }
    
    const int N = 3e5 + 233;
    
    int n, m, X[N], Y[N], p, pt[N][2];
    int ch[N * 35][2], sum[N * 35], tot, root[N];
    
    inline int insert(int pre, int val) {
      int now = ++tot, ret = now;
      for (int i = 31; ~i; --i) {
        int t = (val >> i) & 1;
        ch[now][t ^ 1] = ch[pre][t ^ 1];
        pre = ch[pre][t];
        now = ch[now][t] = ++tot;
        sum[now] = sum[pre] + 1;
      }
      return ret;
    }
    
    inline int solve(int x1, int x2, int y1, int y2, int k) {
      k = (x2 - x1 + 1) * (y2 - y1 + 1) - k + 1;
      for (int i = x1; i <= x2; ++i) {
        pt[i][0] = root[y1 - 1];
        pt[i][1] = root[y2];
      }
      int ret = 0;
      for (int s = 31; ~s; --s) {
        int cnt = 0;
        for (int i = x1; i <= x2; ++i) {
          int t = (X[i] >> s) & 1;
          cnt += sum[ch[pt[i][1]][t]] - sum[ch[pt[i][0]][t]];
        }
        int nxt = k <= cnt ? 0 : 1;
        if (nxt) k -= cnt;
        ret = (ret << 1) | nxt;
        for (int i = x1; i <= x2; ++i) {
          int t = ((X[i] >> s) & 1) ^ nxt;
          pt[i][0] = ch[pt[i][0]][t];
          pt[i][1] = ch[pt[i][1]][t];
        }
      }
      return ret;
    }
    
    int main() {
      n = rd(), m = rd();
      for (int i = 1; i <= n; ++i)
        X[i] = rd();
      for (int i = 1; i <= m; ++i) {
        Y[i] = rd();
        root[i] = insert(root[i - 1], Y[i]);
      }
      p = rd();
      while (p--) {
        int x1 = rd(), x2 = rd(), y1 = rd(), y2 = rd(), k = rd();
        printf("%d\n", solve(x1, x2, y1, y2, k));
      }
      return 0;
    }
    
    • 1

    信息

    ID
    4649
    时间
    2000ms
    内存
    500MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者