• 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;
    }
  • 相关阅读:
    集合的整体
    StringBuffer类中的东西
    ChickHouse安装介绍
    Flink集群搭建
    hadoop-MapReduce总结
    hadoop-hdfs
    linux命令总结
    linux
    shall 2-13
    String 类的其他功能
  • 原文地址:https://www.cnblogs.com/Zinn/p/9301536.html
Copyright © 2020-2023  润新知