zoukankan      html  css  js  c++  java
  • CF1100F Ivan and Burgers

    CF1100F Ivan and Burgers

    静态区间,选取任意个数使得它们的异或和最大

    (n, mleq5 imes10^5, a_iin[0, 10^6])

    lxl ST表,线性基


    如果暴力维护线性基,线段树时间复杂度为 (O(nlog^2n)-O(log^3n))

    由于重复元素对答案没有影响,于是可以用 ST表 维护,时间复杂度为 (O(nlog^3n)-O(log^2n))

    两种做法都无法通过本题。

    如果沿用这个思路,瓶颈显然在线性基合并的 (O(log^2n)) 上,无法再加优化

    线段树做法显然无法再加拓展(和 lxl ST表时间复杂度一样的猫树空间复杂度多一只 (log) ),于是考虑拓展 ST表 做法

    常见的 RMQ 有 ST表 的 (O(nlog n)-O(1)) 的做法,但 (O(n)-O(1)) 的标准RMQ很难写、常数较大,且无法解决本题,于是可以考虑在随机数据下期望 (O(n)-O(1)) 的 lxl ST表

    分块,大小设为 (x)

    预处理每个块两端到块内每个点的前缀 (max) 和后缀 (max)

    预处理块间ST表

    若查询 ([l, r]) ,且 (l, r) 分别在块 (a, b)

    比如说我查l,r,这两个分别在块a,b中

    则查块 (a, b) 之间的 RMQ ,以及 (l)(a) 块的后缀 (max)(r)(b) 块的前缀 (max)

    (l, r) 在同一块中时,暴力求解

    可以取 (x=log n) ,当 (l, r) 不在同一块中时,这个算法是 (O(1))

    摘自 P3793 由乃救爷爷

    如上维护,预处理块中前缀后缀线性基 (O(nlog n)) ,块间ST表线性基 (O(frac{n}{x}log nlog^2n)=O(nlog^2n))

    (l, r) 在同一块中,将 ([l, r]) 中的元素暴力插入线性基, (O(xlog n)=O(log^2n)) ;若 (l, r) 不在同一块中,合并前缀后缀块间三个线性基 (O(log^2n))

    综上所述,时间复杂度 (O(nlog^2n)) ,空间复杂度 (O(nlog n)) 可能还需要卡卡常

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 5e5 + 10, maxm = 7850, base = 63;
    int n, m, tot, lg[maxm], a[maxn];
    
    #define get(x) (((x) + base) >> 6)
    
    struct linear_base {
      int a[20];
    
      inline void clr() {
        memset(a, 0, sizeof a);
      }
    
      inline void ins(int x, int lim = 19) {
        for (int i = lim; ~i; --i) {
          if (x >> i & 1) {
            if (!a[i]) { a[i] = x; return; }
            x ^= a[i];
          }
        }
      }
    
      inline int query() {
        int res = 0;
        for (int i = 19; ~i; --i) {
          if ((res ^ a[i]) > res) res ^= a[i];
        }
        return res;
      }
    } null, lef[maxn], rig[maxn], val[13][maxm];
    
    inline linear_base operator + (linear_base A, const linear_base &B) {
      for (int i = 19; ~i; --i) {
        if (B.a[i]) A.ins(B.a[i], i);
      }
      return A;
    }
    
    const int maxn_r = maxn * 23, maxn_w = maxn * 8;
    char buf_r[maxn_r], *now_r = buf_r;
    char buf_w[maxn_w], *now_w = buf_w;
    
    inline int read() {
      int x = 0;
      while (*now_r < 48) ++now_r;
      while (*now_r > 47) x = (x << 3) + (x << 1) + (*now_r ^ 48), ++now_r;
      return x;
    }
    
    inline void write(int x) {
      static char *tp, st[7];
      if (!x) *now_w = 48, ++now_w;
      for (tp = st; x; *++tp = x % 10 | 48, x /= 10);
      while (tp != st) *now_w = *tp, ++now_w, --tp;
      *now_w = 10, ++now_w;
    }
    
    inline linear_base query(const int &l, const int &r) {
      if (l > r) return null;
      const int k = lg[r - l + 1];
      return val[k][l] + val[k][r - (1 << k) + 1];
    }
    
    int main() {
      fread(buf_r, 1, maxn_r, stdin);
      n = read(), tot = get(n);
      for (int i = 1; i <= n; ++i) {
        a[i] = read();
        val[0][get(i)].ins(a[i]);
      }
      for (int i = 2; i <= tot; ++i) {
        lg[i] = lg[i >> 1] + 1;
      }
      linear_base lst;
      lst.clr();
      for (int i = 1; i <= n; ++i) {
        lst.ins(a[i]), lef[i] = lst;
        if (!(i & base)) lst.clr();
      }
      lst.clr();
      for (int i = n; i; --i) {
        if (!(i & base)) lst.clr();
        lst.ins(a[i]), rig[i] = lst;
      }
      for (int i = 1; i <= lg[tot]; ++i) {
        for (int j = 1; j + (1 << i) - 1 <= tot; ++j) {
          val[i][j] = val[i - 1][j] + val[i - 1][j + (1 << (i - 1))];
        }
      }
      m = read();
      register linear_base ans;
      for (int q = 1; q <= m; ++q) {
        const int l = read(), r = read();
        const int L = get(l), R = get(r);
        ans.clr();
        if (L == R) {
          for (register int i = l; i <= r; ++i) {
            ans.ins(a[i]);
          }
        } else {
          ans = rig[l] + lef[r] + query(L + 1, R - 1);
        }
        write(ans.query());
      }
      fwrite(buf_w, 1, now_w - buf_w, stdout);
      return 0;
    }
    
  • 相关阅读:
    springboot内置tomcat配置虚拟路径
    微信公众号支付备忘及填坑之路-java
    本地调试微信接口(内网穿透到外网)(公网访问局域网程序)
    SSM项目使用GoEasy 获取客户端上下线实时状态变化及在线客户列表
    SSM项目整合Quartz
    spring整合quartz异常:org.quartz.JobPersistenceException: Couldn't clean volatile data: Unknown column 'IS_VOLATILE' in 'where clause'
    Java NIO技术总结
    你懂redis吗
    mysql排序,同样的sql,mysql 每次查询结果顺序不一致
    mysql 不同索引的区别和适用情况总结
  • 原文地址:https://www.cnblogs.com/Juanzhang/p/10877782.html
Copyright © 2011-2022 走看看