[51nod 1295]Xor key(可持久化trie)

[51nod 1295]Xor key(可持久化trie)

题面

给出一个长度为n的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R)。求A[L] 至 A[R] 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少?

分析

可持久化trie裸题

代码

#include<iostream>
#include<cstdio>
#define maxb 31
#define maxn 200000
#define maxs 6400000
using namespace std;
inline void qread(int &x){
    x=0;
    int sign=1;
    char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-') sign=-1;
        c=getchar();
    }
    while(c>='0'&&c<='9'){
        x=x*10+c-'0';
        c=getchar();
    }
    x=x*sign;
}
inline void qprint(int x){
    if(x<0){
        putchar('-');
        qprint(-x);
    }else if(x==0){
        putchar('0');
        return;
    }else{
        if(x>=10) qprint(x/10);
        putchar('0'+x%10);
    }
}

int n,q;
int a[maxn+5];

struct persist_trie{
    int sz[maxs+5];
    int root[maxn+5];
    int son[maxs+5][2];
    int ptr=0;
    void insert(int pos,int val){
        int now=root[pos]=++ptr;
        int last=root[pos-1];
        for(int i=maxb;i>=0;i--){
            sz[now]=sz[last]+1;
            int k=(val>>i)&1;
            son[now][k]=++ptr;
            son[now][k^1]=son[last][k^1];
            now=son[now][k];
            last=son[last][k];
        }
        sz[now]=sz[last]+1;
    }
    int query(int l,int r,int val){
        int now=root[r];
        int last=root[l-1];
        int ans=0;
        for(int i=maxb;i>=0;i--){
            int k=(val>>i)&1;
            int lsz=sz[son[now][k^1]]-sz[son[last][k^1]];
            if(lsz){
                now=son[now][k^1];
                last=son[last][k^1];
                ans=ans*2+1;
            }else{
                now=son[now][k];
                last=son[last][k];
                ans=ans*2;
            }
        }
        return ans;
    }
}T;

int main(){
//  freopen("1.in","r",stdin);
//  freopen("1.ans","w",stdout);
    int l,r,x;
    qread(n);
    qread(q);
    for(int i=1;i<=n;i++){
        qread(a[i]);
        T.insert(i,a[i]);
    }
    for(int i=1;i<=q;i++){
        qread(x);
        qread(l);
        qread(r);
        l++;
        r++;
        qprint(T.query(l,r,x));
        putchar('\n');
    }
}

原文地址:https://www.cnblogs.com/birchtree/p/11624657.html

时间: 2024-10-10 04:16:29

[51nod 1295]Xor key(可持久化trie)的相关文章

51nod 1295 XOR key (可持久化Trie树)

1295 XOR key  题目来源: HackerRank 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题 给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求A[L] 至 A[R] 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少? Input 第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= 

【函数式Trie】51NOD 1295 XOR key

通道 思路:每个数建个31位的树,处理好关系即可 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 60007; const int BIT = 32; int n, m; int tot, s[N * BIT], a[N * BIT][2], root[N]; void Insert(int x, int &y, in

BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对dfs序建可持久化的trie树.这样做的空间复杂度是O(nw),时间复杂度是O(nw). 代码: 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=102000; 5 6 int n,q; 7 int v[maxn

[Luogu P4735]最大异或和(可持久化Trie)

[Luogu P4735]最大异或和(可持久化Trie) 题面 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类型: 1.Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1. 2.Qlrx:询问操作,你需要找到一个位置p,满足l<=p<=r,使得:a[p] xor a[p+1] xor ... xor a[N] xor x 最大,输出最大是多少. 分析 维护\(sum[i]=sum[i-1] \ \text{XOR} \ a[i]\),那么答案就是\(sum[

51Nod - 1295:XOR key (可持久化Trie求区间最大异或)

给出一个长度为N的正整数数组A,再给出Q个查询,每个查询包括3个数,L, R, X (L <= R).求ALL 至 ARR 这R - L + 1个数中,与X 进行异或运算(Xor),得到的最大值是多少?Input第1行:2个数N, Q中间用空格分隔,分别表示数组的长度及查询的数量(1 <= N <= 50000, 1 <= Q <= 50000). 第2 - N+1行:每行1个数,对应数组A的元素(0 <= Aii <= 10^9). 第N+2 - N+Q+1行:

【暖*墟】#数据结构# 可持久化Trie 与 XOR问题

0/1 Trie [例题]最长异或路径 给定一棵n个点的带权树,求树中最长的异或路径. Solution 01字典树:用于解决xor问题. 用dis[i]表示‘从i点到根节点的路径异或和’. ---> 那么问题转化为:求两点dis的异或最大值. 一般查询两数的最大异或值时,都是从最高位到最低位,由此建立Trie树. 利用贪心的思想:对 dis[ ] 建一棵trie树,对于每个数,每次选相反的位置. 即:如果x这一位是1,在tire树上往0跑,反之往1跑. #include<iostream&g

【BZOJ2741】【块状链表+可持久化trie】FOTILE模拟赛L

Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y): l = min ( ((x+lastans) mod N)+1 , ((y+lastans) mod N)+1 ).r = max ( ((x+lastans) mod N)+1 , ((y+last

BZOJ 3261: 最大异或和 [可持久化Trie]

3261: 最大异或和 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1513  Solved: 657[Submit][Status][Discuss] Description 给定一个非负整数序列 {a},初始长度为 N.       有   M个操作,有以下两种操作类型: 1 .A x:添加操作,表示在序列末尾添加一个数 x,序列的长度 N+1.2 .Q l r x:询问操作,你需要找到一个位置 p,满足 l<=p<=r,使得: a[p]

bzoj 2741: 【FOTILE模拟赛】L 分塊+可持久化trie

2741: [FOTILE模拟赛]L Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1116  Solved: 292[Submit][Status] Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 ... xor Aj),其中l<=i<=j<=r. 为了体现在线操作,对于一个询问(x,y):