最大异或和 HYSBZ - 3261

本文深入探讨了可持久化字典树和主席树的实现原理及应用,通过具体代码示例,讲解了如何使用这两种数据结构进行高效的数据查询和更新操作,特别适用于处理区间查询和历史版本数据的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://www.lydsy.com/JudgeOnline/problem.php?id=3261

可持久化字典树存模板 和主席树差不多 每次更新动态开点

题目查询的是某个异或后缀 利用异或自反性 把前缀插入树中 查后缀就异或整个区间即可

#include <bits/stdc++.h>
using namespace std;

struct node
{
    int c[2];
    int sum;
};

node tree[15000010];
int a[600010],b[600010],root[600010];
int bin[50];
int n,q,num;

void init()
{
    int i;
    bin[0]=1;
    for(i=1;i<=30;i++) bin[i]=2*bin[i-1];
}

int update(int rot,int val)
{
    int res,cur,i,id;
    res=cur=num++;
    for(i=24;i>=0;i--)
    {
        //c[cur][0]=c[rot][0];
        //c[cur][1]=c[rot][1];
        //sum[cur]=sum[rot]+1;
        tree[cur]=tree[rot];
        tree[cur].sum++;
        id=val&bin[i];
        id>>=i;
        //c[cur][id]=num++;
        //cur=c[cur][id];
        //rot=c[rot][id];
        tree[cur].c[id]=num++;
        cur=tree[cur].c[id];
        rot=tree[rot].c[id];
    }
    tree[cur]=tree[rot];
    tree[cur].sum++;
    return res;
}

int query(int lrot,int rrot,int val)
{
    int res,i,id;
    res=0;
    for(i=24;i>=0;i--)
    {
        id=val&bin[i];
        id>>=i;
        if(tree[tree[rrot].c[id^1]].sum-tree[tree[lrot].c[id^1]].sum>0) res+=bin[i],lrot=tree[lrot].c[id^1],rrot=tree[rrot].c[id^1];
        else lrot=tree[lrot].c[id],rrot=tree[rrot].c[id];
    }
    return res;
}

int main()
{
    int i,tmp,val,l,r;
    char op[10];
    init();
    scanf("%d%d",&n,&q);
    tmp=0,n++,num++;
    root[1]=update(root[0],tmp);
    for(i=2;i<=n;i++)
    {
        scanf("%d",&val);
        tmp^=val;
        root[i]=update(root[i-1],tmp);
    }
    while(q--)
    {
        scanf("%s",op);
        if(op[0]=='A')
        {
            n++;
            scanf("%d",&val);
            tmp^=val;
            root[n]=update(root[n-1],tmp);
        }
        else
        {
            scanf("%d%d%d",&l,&r,&val);
            printf("%d\n",query(root[l-1],root[r],val^tmp));
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值