BZOJ 3261: 最大异或和|可持久化Tire树

本文介绍了一种使用可持久化Tire树解决异或和最大化的算法实现。该方法通过维护数组的异或和,并利用可持久化Tire树进行查询,以找到使指定表达式结果最大的解。

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

a[i]为前i个数的异或和,Ans=x(xor)a[n](xor)a[p1]使其最大化,然后可以用可持久化Tire树来维护一下.
数组开的一定要够大,1000W还是会跪!!!!

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define mx 1e9
#define lowbit(x) (x&(-x))
#define N 505
using namespace std;
int sc()
{
    int i=0,f=1; char c=getchar();
    while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
    return i*f;
}
int ch[14000050][2],sum[14000050];
int v[600066],root[600066];
int n,cnt,Sum,m;
void add(int pre,int &x,int w,int k)
{
    if(!x)x=++cnt;
    sum[x]=sum[pre]+1;
    if(!k)return;
    bool e=(w&k);
    ch[x][!e]=ch[pre][!e];
    add(ch[pre][e],ch[x][e],w,k>>1);
}
int ask(int l,int r,int x)
{
    int k=1<<24,ans=0;
    while(k)
    {
        bool e=!(x&k); 
        if(sum[ch[r][e]]-sum[ch[l][e]])
            ans+=k,r=ch[r][e],l=ch[l][e];
        else
            r=ch[r][!e],l=ch[l][!e];
        k>>=1;
    }
    return ans;
}
int main()
{
    n=sc()+1;m=sc();v[1]=0;
    for(int i=2;i<=n;i++)v[i]=v[i-1]^sc();
    for(int i=1;i<=n;i++)
        add(root[i-1],root[i],v[i],1<<24);
    for(int i=1;i<=m;i++)
    {
        char s[10];
        scanf("%s",s);
        if(s[0]=='A')
            ++n,v[n]=v[n-1]^sc(),
            add(root[n-1],root[n],v[n],1<<24);
        else
        {
            int l=sc()-1,r=sc(),x=sc()^v[n];
            printf("%d\n",ask(root[l],root[r],x));
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值