最大异或和
题意:转化后的题意是有一种操作+一种询问:
 1. 操作:在序列末尾插入一个数
 2. 询问:给定     l,r,x,求区间     l,r中与     x异或能得到的最大异或值(转化后的题意)
思路:题意都被转化成这样了。。。应该就没啥难度了
- 用类似主席树的方式构建可持久化 01trie
- 然后还是简单的贪心跑 01trie
- 最后小心给定的 l,r都等于 1的情况,特判一下即可(还没有想好如何不特判)
题面描述
#include "bits/stdc++.h"
#define hhh printf("hhh\n")
#define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
inline int read() {int x=0;char c=getchar();while(c<'0'||c>'9')c=getchar();while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x;}
const int maxn = 6e5+10;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
const double eps = 1e-7;
int N, M;
int root[maxn], son[maxn<<5][2], sz[maxn<<5], tot;
void insert(int p, int i, int pre, int &now) {
    sz[now=++tot]=sz[pre]+1;
    if(i<0) return;
    int s=p>>i&1;
    son[now][!s]=son[pre][!s];
    insert(p,i-1,son[pre][s],son[now][s]);
}
int query(int x, int y, int p, int i) {
    if(i<0) return 0;
    int s=p>>i&1;
    if(sz[son[y][!s]]-sz[son[x][!s]]>0) return (1<<i)+query(son[x][!s],son[y][!s],p,i-1);
    return query(son[x][s],son[y][s],p,i-1);
}
int main() {
    //ios::sync_with_stdio(false); cin.tie(0);
    N=read(), M=read();
    int pre=0;
    insert(0,30,root[0],root[0]);
    for(int i=1; i<=N; ++i) insert(pre^=read(),30,root[i-1],root[i]);
    while(M--) {
        char s[2]; scanf("%s", s);
        if(s[0]=='A') insert(pre^=read(),30,root[N],root[N+1]), ++N;
        else {
            int l=read()-1, r=read()-1, x=pre^read();
            if(l==r&&l==0) printf("%d\n", x);
            else printf("%d\n", query(root[max(0,l-1)],root[r],x,30));
        }
    }
}

 京公网安备 11010502036488号
京公网安备 11010502036488号