线性基模板

struct Base {
  
  static const int maxN = 62;//int-31 or long long-62
  
  int tot, flag;
  LL d[maxN + 5];
  LL nd[maxN + 5];
  
  Base() {
    tot = flag = 0;
    memset(d, 0, sizeof d);
    memset(nd, 0, sizeof nd);
  }

  bool ins(LL x) {
    for (int i = maxN; ~i; i--) {
      if (x & (1LL << i)) {
        if (d[i]) {
          x ^= d[i];
        } else {
          d[i] = x;
          return true;
        }
      }
    }
    flag = 1;
    return false;
  }
  
  bool canIns(LL x) {
    for (int i = maxN; ~i; i--) {
      if (x & (1LL << i)) {
        if (d[i]) {
          x ^= d[i];
        } else {
          return true;
        }
      }
    }
    return false;
  }

  LL queryMax() {
    LL ans = 0;
    for (int i = maxN; ~i; i--) ans = max(ans, ans ^ d[i]);
    return ans;
  }

  LL queryMin() {
    for (int i = 0; i <= maxN; i++) if (d[i]) return d[i];
    return -1LL;
  }

  void rebuild() {//ÇókthÇ°, ÏÈrebuild 
    for (int i = maxN; ~i; i--) {
      for (int j = i - 1; ~j; j--) {
        if (d[i] & (1LL << j)) d[i] ^= d[j];
      }
    }
    for (int i = 0; i <= maxN; i++) if (d[i])
        nd[tot++] = d[i];
  }

  LL kth(LL k) {
    if (flag) k--;
    if (!k) return 0LL;
    if (k >= (1LL << tot)) return -1LL;
    LL ans = 0;
    for (int i = maxN; ~i; i--) {
      if (k & (1LL << i)) ans ^= nd[i];
    }
    return ans;
  }

  void merge(Base b) {//ÓëbÈ¡²¢¼¯
    for (int i = maxN; ~i; i--) if (b.d[i])
        ins(b.d[i]);
  }

  Base mixed(Base B) {//ÓëbÈ¡½»¼¯
    Base All, C, D;
  //  All.init(), C.init(), D.init();
    for (int i = maxN; ~i; i--) {
      All.d[i] = d[i];
      D.d[i] = 1LL << i;
    }
    for (int i = maxN; ~i; i--) {
      if (B.d[i]) {
        LL v = B.d[i], k = 0;
        bool can = true;
        for (int j = maxN; ~j; j--) {
          if (v & (1LL << j)) {
            if (All.d[j]) {
              v ^= All.d[j];
              k ^= D.d[j];
            } else {
              can = false;
              All.d[j] = v;
              D.d[j] = k;
              break;
            }
          }
        }

        if (can) {
          LL v = 0;
          for (int j = maxN; ~j; j--) {
            if (k & (1LL << j)) {
              v ^= d[j];
            }
          }
          C.ins(v);
        }
      }
    }
    return C;
  }

} lb;

posted @ 2019-10-28 00:34  Chase。  阅读(101)  评论(0编辑  收藏  举报