comet oj #3 D 区间维护异或后的线性基

Posted nervendnig

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了comet oj #3 D 区间维护异或后的线性基相关的知识,希望对你有一定的参考价值。

这不是原题吗...

具体做法参考codefores 587 E

不过这题卡常...

写题解纯粹是为了记录一下快读...

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define rep(ii,a,b) for(register int ii=a;ii<=b;++ii)
#define per(ii,a,b) for(register int ii=b;ii>=a;--ii)
using namespace std;
const int maxn=5e4+10,maxm=2e5+10;
int casn,n,m,k,val[maxn],curpos = 0, iseof;
struct bass{
  int flag,val;
  int d[33];
  inline void init(){val=flag=0;memset(d,0,sizeof d);}
  inline void insert(ll x){
    for(register int i=30;x&&i>=0;--i)
        if(x&(1ll<<i)){
          if(!d[i]) {d[i]=x;return;}
          else x^=d[i];
        }
  }
  inline int query(int x){
    register int ans=x;
    per(i,0,30){
      if((ans^d[i])>ans) {
        ans^=d[i];
      }
    }
    return ans;
  }
  inline void update(int x){val^=x;flag^=x;}
};
namespace segtree{
  #define nd node[now]
  #define ndl node[now<<1]
  #define ndr node[now<<1|1]
  inline bass marge(bass &a,bass b) {
    bass ans;ans.init();
    per(i,0,30) ans.insert(a.d[i]),ans.insert(b.d[i]);
    ans.insert(a.val^b.val);
    ans.val=a.val;
    return ans;
  }
  bass node[maxn<<2|3];
  inline void down(int now){
    if(nd.flag){
      ndl.update(nd.flag);ndr.update(nd.flag);
      nd.flag=0;
    }
  }
  void maketree(int s,int t,int now=1){
    nd.init();
    if(s==t) {nd.val=val[s];return ;}
    maketree(s,(s+t)/2,now<<1);
    maketree((s+t)/2+1,t,now<<1|1);
    nd=marge(ndl,ndr);
  }
  void update(int s,int t,int x,int l,int r,int now=1){
    if(s<=l&&t>=r) {nd.update(x);return;}
    down(now);int mid=(l+r)/2;
    if(s<=mid) update(s,t,x,l,mid,now<<1);
    if(t>mid) update(s,t,x,mid+1,r,now<<1|1);
    nd=marge(ndl,ndr);
  }
  bass ans;
  void query(int s,int t,int l,int r,int now=1){
    if(s<=l&&t>=r) {
        ans=marge(ans,nd);
        return ;
    }
    down(now);int mid=(l+r)/2;
    if(s<=mid) query(s,t,l,mid,now<<1);
    if(t>mid) query(s,t,mid+1,r,now<<1|1);
  }
}
inline void write(int x) {if(x>9) write(x / 10);putchar(x % 10 + ‘0‘);}
char buf[100 * 1024 * 1024 + 5];
int nxint() {
  if (iseof) return 0;
  register int ret = 0,flg = 0;
  while (!(‘0‘ <= buf[curpos] && buf[curpos] <= ‘9‘)) {
    if (buf[curpos] == 0) {
      if (fgets(buf, 16 * 1024 * 1024, stdin) == NULL) iseof = true;
      curpos = 0;
      continue;
    }
    curpos++;
  }
  if (curpos && buf[curpos - 1] == ‘-‘) flg = -1;
  else flg = 1;
  while (‘0‘ <= buf[curpos] && buf[curpos] <= ‘9‘) {
    ret = ret * 10 + (buf[curpos] - ‘0‘);
    curpos++;
  }
  return ret * flg;
}
int main() {
    n=nxint(),m=nxint();
    register int a,b,c,d;
    rep(i,1,n) val[i]=nxint();
    segtree::maketree(1,n);
    rep(i,1,m){
        a=nxint();b=nxint();c=nxint();d=nxint();
        if(a==1)segtree::update(b,c,d,1,n);
        else {
          segtree::ans.init();
          segtree::query(b,c,1,n);
        write(segtree::ans.query(d));
        putchar(‘\\n‘);
    }
}

 

以上是关于comet oj #3 D 区间维护异或后的线性基的主要内容,如果未能解决你的问题,请参考以下文章

[ [Ynoi2013] 无力回天 NOI2017 ] 解题报告

CodeForces - 587E(线性基+线段树+差分)

CodeForces - 587E(线性基+线段树+差分)

LeetCode﹝异或ி﹞解码异或区间查询第k大异或值

LeetCode﹝异或ி﹞解码异或区间查询第k大异或值

LeetCode﹝异或ி﹞解码异或区间查询第k大异或值