bzoj4260 REBXOR——Trie树

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4260

对于每个位置,求一个前缀最大值和后缀最大值;

也就是从1到 i 的异或和要找前面某处的一个异或和,异或一下就有了一段区间的异或和;

要最大化这个值,就是从前面所有异或和中找到恰好和这个值相反的,所以可以在前面所有异或和构建出的 Trie 树上查找;

学习了一下写 Trie 树的姿势!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=4e5+5;
int n,a[maxn],c[maxn*30][3],tot,f[maxn],g[maxn],ans;
void insert(int x)
{
    int nw=0;
    for(int i=(1<<30);i;i>>=1)
    {
        bool w=(x&i); //w可能不只是 0 或 1 !
        if(!c[nw][w])c[nw][w]=++tot;
        nw=c[nw][w];
    }
}
int query(int x)
{
    int nw=0,ret=0;
    for(int i=(1<<30);i;i>>=1)
    {
//        int w=(x&i); //w可能不只是 0 或 1 !
        bool w=(x&i); w=!w; 
        if(c[nw][w])ret+=i,nw=c[nw][w];
        else nw=c[nw][w^1];
    }
    return ret;
}
int main()
{
    scanf("%d",&n);
    insert(0); int nw=0;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
    {
        nw^=a[i];
        f[i]=max(f[i-1],query(nw));
        insert(nw);
    }
    memset(c,0,sizeof c);
    tot=0; nw=0; insert(0);
    for(int i=n;i;i--)
    {
        nw^=a[i];
        g[i]=max(g[i+1],query(nw));
        insert(nw);
    }
    for(int i=1;i<=n;i++)ans=max(ans,f[i]+g[i+1]);//g[i+1] 
    printf("%d",ans);
    return 0;
}

 

转载于:https://www.cnblogs.com/Zinn/p/9301536.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值