bzoj 3261: 最大异或和 可持久化Trie

為{幸葍}努か 提交于 2019-11-28 04:44:08

题目大意:

http://www.lydsy.com/JudgeOnline/problem.php?id=3261

题解

首先我们转化一下,设sum[x]表示1~x的异或和
这样我们知道原来的询问转化为
在[l-1,r-1]内选择一个值,设为y
最大化y^sum[n]^x,其中sum[n]^x是一开始的给定值
那么问题就转化成了在一个区间内求一个数和已知数异或最大
所以我们直接裸上Trie树可以搞定
但是对于这个东西是要查一个区间内的,所以我们可持久化一下就好了

#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
    x=0;char ch;bool flag = false;
    while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
    while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
const int maxn = 600010;
struct Node{
    Node *ch[2];
    int ed;
}*null,*rt[maxn];
Node mem[maxn*28],*it;
inline void init(){
    it = mem;null = it++;
    null->ch[0] = null->ch[1] = null;
    null->ed = 0;
}
Node *insert(Node *rt,int x,int d){
    Node *p = it++;(*p = *rt);
    p->ed++;
    if(d == -1) return null;
    if( ( x & (1 << (d-1) ) )) p->ch[1] = insert(p->ch[1],x,d-1);
    else p->ch[0] = insert(p->ch[0],x,d-1);
    return p;
}
int ans = 0;
void query(Node *x,Node *y,int val,int d){
    if(d == 0) return ;
    int id = (val&(1 << (d-1)));
    if(id){
        if(y->ch[0]->ed - x->ch[0]->ed > 0){
            ans ^= (1 << (d-1));
            query(x->ch[0],y->ch[0],val,d-1);
        }else query(x->ch[1],y->ch[1],val,d-1);
    }else{
        if(y->ch[1]->ed - x->ch[1]->ed > 0){
            ans ^= (1 << (d-1));
            query(x->ch[1],y->ch[1],val,d-1);
        }else query(x->ch[0],y->ch[0],val,d-1);
    }
}
int a[maxn];
int main(){
    init();rt[0] = null;
    int n,m;read(n);read(m);
    for(int i=1;i<=n;++i){
        read(a[i]);a[i]^=a[i-1];
        rt[i] = insert(rt[i-1],a[i],26);
    }
    char ch;int l,r,x;
    while(m--){
        while(ch=getchar(),ch<'!');
        read(l);
        if(ch == 'A'){
            a[n+1] = l;a[n+1] ^= a[n];
            rt[n+1] = insert(rt[n],a[n+1],26);
            ++n;
        }else{
            read(r);read(x);
            if(l == r){
                printf("%d\n",a[n]^a[l-1]^x);
                continue;
            }
            --l;--r;x ^= a[n];
            ans = 0;
            bool flag = false;
            if(l == 0){
                l = 1;
                flag = true;
            }
            query(rt[l-1],rt[r],x,26);
            if(flag) ans = max(ans,x);
            printf("%d\n",ans);
        }
    }
    getchar();getchar();
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!