BZOJ 3261 最大异或和

Posted ziliuziliu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3261 最大异或和相关的知识,希望对你有一定的参考价值。

可持久化trie。

一个重要的思想是前缀和。

然后SB错误调了一晚上。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 600500
using namespace std;
int n,m,x,y,z,tot=0,tree[maxn*25][3],sum[maxn*25],root[maxn];
int a[maxn],b[maxn],bin[30];
char type[4];
void gettable()
{
    bin[0]=1;
    for (int i=1;i<=24;i++)
        bin[i]=bin[i-1]<<1;
}
void insert(int bitt,int last,int &now,int x)
{
    now=++tot;
    tree[now][0]=tree[last][0];tree[now][1]=tree[last][1];
    sum[now]=sum[last]+1;
    if (bitt==-1) return;
    int tmp=x&bin[bitt];tmp>>=bitt;
    insert(bitt-1,tree[last][tmp],tree[now][tmp],x);
}
int query(int bitt,int last,int now,int x)
{
    if (bitt==-1) return 0;
    int tmp=x&bin[bitt];tmp>>=bitt;
    if (sum[tree[now][tmp^1]]-sum[tree[last][tmp^1]])
        return query(bitt-1,tree[last][tmp^1],tree[now][tmp^1],x)+bin[bitt];
    else return query(bitt-1,tree[last][tmp],tree[now][tmp],x);
}
void work1()
{
    n++;
    scanf("%d",&x);
    a[n]=x;b[n]=b[n-1]^x;
    insert(23,root[n-1],root[n],b[n]);
}
void work2()
{
    scanf("%d%d%d",&x,&y,&z);
    printf("%d\n",query(23,root[x-1],root[y],b[n]^z));
}
int main()
{
    gettable();
    scanf("%d%d",&n,&m);
    n++;a[1]=0;b[1]=0;
    for (int i=2;i<=n;i++)
    {
        scanf("%d",&a[i]);
        b[i]=b[i-1]^a[i];
    }    
    for (int i=1;i<=n;i++)
        insert(23,root[i-1],root[i],b[i]);
    for (int i=1;i<=m;i++)
    {
        scanf("%s",type);
        if (type[0]==A) work1();
        else work2();
    }
    return 0;
}

 

以上是关于BZOJ 3261 最大异或和的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 3261 最大异或和

Bzoj3261 最大异或和

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

bzoj3261最大异或和

bzoj 3261: 最大异或和 (可持久化trie树)

BZOJ3261:最大异或和——题解