bzoj 3261 最大异或和 可持久化trie树

查询 i 属于【l,r】 中  p[i] ^ p[i+1 ] ^ ….^p[n]^x 中的最大值

b【i】 为 p【1】^p【2】^……^p【i】 的异或值。

也就是查询   b【i-1】^ b【n】^ X    (i属于 [l,r])

也就是变成在 一个区间中查询 对于A = (b[n]^ X)的最大的异或值。

所以应该维护 b【i-1】。

trick 对于 i =1  b[0] = 0;  没有想到。 如果不插入 0的话, 结果p[i] ^ p[i+1 ] ^ ….^p[n]^x 中不会选到第一个节点。

i=2 b[1] = a[1];

i =3  b[2]= a[1]^a[2].

利用可持久化tire树,可以实现 在区间中 查询区间中的  数 跟 X异或和 最大值。

/**************************************************************
    Problem: 3261
    User: OceanLight
    Language: C++
    Result: Accepted
    Time:4228 ms
    Memory:294360 kb
****************************************************************/
 
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <cstring>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <assert.h>
#include <queue>
#define REP(i,n) for(int i=0;i<n;i++)
#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)
#define ALLL(x) x.begin(),x.end()
#define SORT(x) sort(ALLL(x))
#define CLEAR(x) memset(x,0,sizeof(x))
#define FILLL(x,c) memset(x,c,sizeof(x))
using namespace std;
const double eps = 1e-9;
#define LL long long
#define pb push_back
const int maxn  = 610000;
int a[maxn],b[maxn];
struct Node{
   Node *s[2];
   int sum;
}nodes[maxn*40];
Node *root[maxn],*null;
int C;
int n,m;
void init(){
    C=0;
    root[0] = null = &nodes[C++];
    null->s[0] = null->s[1] = null;
    null->sum = 0;
}
Node *insert(int v,int d,Node *root){
     Node *rt = &nodes[C++];
     rt->s[0] = root->s[0];
     rt->s[1] = root->s[1];
     rt->sum = root->sum+1;
     if(d<0)return rt;
     int p = (v>>d)&1;
     rt->s[p] = insert(v,d-1,root->s[p]);
     return rt;
}
int query(int v,int d,Node *rt1,Node *rt2){
    if(d<0)return 0;
    int p = (v>>d)&1;
    if(rt2->s[p^1]->sum - rt1->s[p^1]->sum){
          return (1<<d)+query(v,d-1,rt1->s[p^1],rt2->s[p^1]);
    }
    return query(v,d-1,rt1->s[p],rt2->s[p]);
}
const int K = 24;
char tmp[10];
int main(){
    //cout << (1<<K)<<endl;
    while(~scanf("%d%d",&n,&m)){
        init();
        CLEAR(a);
        CLEAR(b);
        n++;
        root[1] = insert(0,K,root[0]);
         for(int i=2;i<=n;i++){
             scanf("%d",&a[i]);
             b[i] = b[i-1]^a[i];
             root[i] = insert(b[i],K,root[i-1]);
         } 
         while(m--){
             scanf("%s",tmp);
             if(tmp[0]=='A'){
                  n++;
                  scanf("%d",&a[n]);
                  b[n] = b[n-1]^a[n];
                  root[n] = insert(b[n],K,root[n-1]);
             }else{
                 int l,r,x;
                 scanf("%d%d%d",&l,&r,&x);
                 int ans = query(x^b[n],K,root[l-1],root[r]);
                 printf("%d\n",ans);
             }
         }
    }
    return 0;
     
}

    原文作者:Trie树
    原文地址: https://blog.csdn.net/OceanLight/article/details/13754381
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞