• 2016.1.9


    可持久化trie处理抑或和最大值

    用trie树从上往下贪心的思想查询区间抑或最大值

    后缀抑或上整体转成维护前缀,方便处理修改

    题目

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define maxn 600020

    struct node{
    int next[2],val;
    }trie[maxn * 30];
    int root[maxn],a[maxn],data[maxn];
    int n,m,tot,xorsum;

    int insert(int now,int x,int bit){
    int cur = ++tot,c = (x >> (bit - 1)) & 1; //不是 x >> (bit - 1)
    trie[cur].val = trie[now].val + 1;
    if ( !bit ) return cur;
    trie[cur].next[c] = insert(trie[now].next[c],x,bit - 1);
    trie[cur].next[c ^ 1] = trie[now].next[c ^ 1];
    return cur;
    }
    int query(int a,int b,int x,int bit){
    int c = (x >> (bit - 1)) & 1,ans = 0;
    if ( !bit ) return 0;
    if ( (trie[trie[a].next[c ^ 1]].val - trie[trie[b].next[c ^ 1]].val) > 0 ){
    ans += query(trie[a].next[c ^ 1],trie[b].next[c ^ 1],x,bit - 1);
    ans += (1 << (bit - 1));
    }
    else{
    ans += query(trie[a].next[c],trie[b].next[c],x,bit - 1);
    }
    /*
    else{
    if ( trie[trie[a].next[c ^ 1]].val - trie[trie[b].next[c ^ 1]].val ){
    ans += query(trie[a].next[c ^ 1],trie[b].next[c ^ 1],x,bit - 1);
    ans += (1 << (bit - 2));
    }
    else{
    ans += query(trie[a].next[c],trie[b].next[c],x,bit - 1);
    }
    }*/
    return ans;
    }
    int main(){
    freopen("xor.in","r",stdin);
    freopen("xor.out","w",stdout);
    scanf("%d %d",&n,&m);
    for (int i = 1 ; i <= n ; i++) scanf("%d",&data[i]);
    a[1] = data[1];
    for (int i = 2 ; i <= n ; i++) a[i] = data[i] ^ a[i - 1];
    xorsum = a[n];
    for (int i = 1 ; i <= n ; i++){
    root[i] = insert(root[i - 1],a[i],25);
    /*cout<<i<<endl;
    for (int j = root[i] ; j <= tot ; j++){
    cout<<j<<" "<<trie[j].val<<" next: "<<trie[j].next[0]<<" "<<trie[j].next[1]<<endl;
    }
    cout<<endl;*/
    }
    while ( m-- ){
    char ch;
    scanf("%s",&ch);
    if ( ch == 'A' ){
    scanf("%d",&data[++n]);
    a[n] = a[n - 1] ^ data[n];
    xorsum ^= data[n];
    root[n] = insert(root[n - 1],a[n],25);
    /* cout<<n<<endl;
    for (int i = root[n] ; i <= tot ; i++){
    cout<<i<<" "<<trie[i].val<<" next: "<<trie[i].next[0]<<" "<<trie[i].next[1]<<endl;
    }
    cout<<endl;*/
    }
    else{
    int l,r,x;
    scanf("%d %d %d",&l,&r,&x);
    x ^= xorsum;
    if ( r == 1 ) printf("%d ",x);
    else
    printf("%d ",query(root[r - 1],root[max(l - 2,0)],x,25)); //因为将后缀转化为前缀来处理,所以区间整体向左平移1,保证r,l两个端点可以被处理
    }
    }
    return 0;
    }

  • 相关阅读:
    作为一个前端,可以如何机智地弄坏一台电脑?
    Mysql数据库字符集问题
    代码扫描工具 SonarQube Scanner 配置 & Jenkins 集成
    【C++】统计代码覆盖率(四)
    【Jenkins】各项配置
    python小知识点汇总
    MobaXterm使用
    PHP代码覆盖率
    golang代码覆盖率
    压测工具Locuse的使用
  • 原文地址:https://www.cnblogs.com/zqq123/p/5119714.html
Copyright © 2020-2023  润新知