zoukankan      html  css  js  c++  java
  • BZOJ3261 最大异或和

    题目链接:戳我

    可持久化01trie~~

    其实还是先求出来前缀异或和,剩下的就是可持久化01trie——其实和主席树差不多,我们对每一个节点都建立一颗trie树。在这个题里面,用cnt[i]来表示节点编号为i的这个点所表示的前缀出现了多少次,我们利用差分思想就可以求出来这个前缀在当前区间中到底有没有出现。

    注意我们建树的时候,假设当前这个节点没有'0'儿子,那我们就直接复制它的父亲的'0'儿子编号即可,(其实应该也可以赋予新的编号,然后让它和父亲的那个子节点相同。。。。不过这样的话更节省空间)然后因为它拥有'1'儿子,所以我们还是要给这个新子节点赋予一个编号,然后cnt++就可以了。

    备注:查询的时候l--,r--的原因是,由于异或的性质,所以我们只需要求p-1,所以我们的区间就更改为了l-1,r-1。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #define MAXN 1000010
    using namespace std;
    int n,m,tot;
    int a[MAXN],rt[MAXN],ch[MAXN*25][2],cnt[MAXN*25];
    inline void insert(int x,int f,int sum)
    {
        for(int i=24;i>=0;i--)
        {
            int v=((sum>>i)&1);
            ch[x][!v]=ch[f][!v];
            ch[x][v]=++tot;
            cnt[ch[x][v]]=cnt[ch[f][v]]+1;
            x=ch[x][v],f=ch[f][v];
        }
    }
    inline int query(int x,int f,int sum)
    {
        int cur_ans=0;
        for(int i=24;i>=0;i--)
        {
            int v=((sum>>i)&1);
            if(cnt[ch[x][!v]]>cnt[ch[f][!v]])
            {
                cur_ans+=(1<<i);
                x=ch[x][!v],f=ch[f][!v];
            }
            else x=ch[x][v],f=ch[f][v];
        }
        return cur_ans;
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        #endif
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) a[i]^=a[i-1];
        rt[0]=++tot;
        insert(rt[0],0,0);
        //for(int i=1;i<=n;i++) printf("a[%d]=%d
    ",i,a[i]);
        for(int i=1;i<=n;i++) rt[i]=++tot,insert(rt[i],rt[i-1],a[i]);
        for(int i=1;i<=m;i++)
        {
            char scur[3];
            int l,r,x;
            scanf("%s",scur);
            if(scur[0]=='A')
            {
                scanf("%d",&x);
                rt[++n]=++tot;
                a[n]=a[n-1]^x;
                insert(rt[n],rt[n-1],a[n]);
            }
            else
            {
                scanf("%d%d%d",&l,&r,&x);
                r--,l--;
                if(l==0) printf("%d
    ",query(rt[r],0,x^a[n]));
                else printf("%d
    ",query(rt[r],rt[l-1],x^a[n]));
            }
        }
        return 0;
    }
    
  • 相关阅读:
    springcloud12-spring cloud stream
    Linux上安装gitbook并拉取git项目编译
    Python 之一条命令生成项目依赖包文件 requirements.txt
    python跨模块使用全局变量的实现方法
    微信朋友圈测试用例
    linux安装maven
    jenkins上集成sonar
    windows上安装sonar并使用其分析项目
    jquery 点击同级元素隐藏,再点击显示
    10进制转16进制自动补全8位 并高低位转换
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10479985.html
Copyright © 2011-2022 走看看