51nod 1577 异或凑数 线性基的妙用

Posted Strove with none.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了51nod 1577 异或凑数 线性基的妙用相关的知识,希望对你有一定的参考价值。

\(OTZgengyf\)。。当场被吊打\(QwQ\)


思路:线性基

提交:\(3\)

错因:往里面加数时\(tmp.p\)\(i\)区分不清(还是我太菜了)

题解:

我们对每个位置的线性基如此操作:
对于每一位,保存尽量靠后的数;
所以每一位还要记录位置。
(后文区分"位"(二进制位)和"位置"(原数组中的第几位),每个位置都有\(30\)位)
具体来说,就是从高位向低位扫,如果我们当前的数能被放入某一位,如果这一位没有数,则直接放入;否则比较出现位置,如果当前数出现位置较为靠后,就把当前数和这一位的数交换,然后从下一位继续进行插入。这样高位上的数会出现的尽量靠后。
查询的时候,从高位到低位进行查询。如果需要某位上面的数而这个数出现的位置\(<l\),直接输出‘NO‘。

#include<cstdio>
#include<iostream>
#define R register int
using namespace std;
namespace Luitaryi {
static char B[1<<15],*S=B,*T=B;
#define getchar() (S==T&&(T=(S=B)+fread(B,1,1<<15,stdin),S==T)?EOF:*S++)
template<class I> inline I g(I& x) { x=0;
  register I f=1; register char ch; while(!isdigit(ch=getchar())) f=ch=='-'?-1:f;
  do x=x*10+(ch^48); while(isdigit(ch=getchar())); return x*=f;
} const int N=5e5+10;
#define pc(x) putchar(x)
struct node {int c,p; node() {}
  node(int _c,int _p):c(_c),p(_p) {}
}f[N][31];
int n,m;
inline void main() {
  g(n); for(R i=1,x;i<=n;++i) { 
    g(x); register node tmp(x,i);
    memcpy(f[i],f[i-1],sizeof(f[i-1]));
    for(R k=30;~k;--k) if(tmp.c&(1<<k)) {
      if(!f[i][k].c) {
        f[i][k].c=tmp.c,f[i][k].p=tmp.p; break;
      } else {
        if(f[i][k].p<tmp.p) swap(tmp.c,f[i][k].c),swap(f[i][k].p,tmp.p);
        tmp.c^=f[i][k].c;
      }
    }
  } g(m); for(R i=1,l,r,x;i<=m;++i) {
    g(l),g(r),g(x);
    for(R k=30;~k;--k) if(x&(1<<k)) {
      if(!f[r][k].c||f[r][k].p<l) {
        pc('N'),pc('O'),pc('\n'); goto end;
      } x^=f[r][k].c;
    } pc('Y'),pc('E'),pc('S'); pc('\n'); end:;
  }
}
} signed main() {Luitaryi::main(); return 0;}

2019.08.12
88

以上是关于51nod 1577 异或凑数 线性基的妙用的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1577 异或凑数(线性基)

51nod 1312 最大异或和(线性基)

51Nod - 1385 凑数字

关于线性基的一丢丢理解

51NOD 1385凑数字(找规律?)

bzoj 4269 再见Xor 线性基