zoukankan      html  css  js  c++  java
  • bzoj 4260 REBXOR —— Trie树

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

    用 Trie 树可以找出前缀异或的最大值和后缀异或的最大值,拼起来即可;

    注意要先加入一个0,表示区间左端点在 0 或右端点在 n+1;

    竟然1A了!感动。

    ——然后发现3个月前做过!!!... https://www.cnblogs.com/Zinn/p/9301536.html

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const xn=4e5+5,mx=30;
    int n,cnt,a[xn],pr[xn],sc[xn],c[xn*mx][2],bin[mx+5];
    int rd()
    {
      int ret=0,f=1; char ch=getchar();
      while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
      while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
      return f?ret:-ret;
    }
    void init()
    {
      bin[0]=1;
      for(int i=1;i<=mx;i++)bin[i]=bin[i-1]*2;
    }
    void add(int x)
    {
      int nw=0;
      for(int i=mx;i>=0;i--)
        {
          bool d=(x&bin[i]);
          if(!c[nw][d])c[nw][d]=++cnt; nw=c[nw][d];
        }
    }
    int query(int x)
    {
      int nw=0,ret=0;
      for(int i=mx;i>=0;i--)
        {
          bool d=!(x&bin[i]);
          if(c[nw][d])nw=c[nw][d],ret+=bin[i];
          else nw=c[nw][!d];
        }
      return ret;
    }
    int main()
    {
      n=rd(); init(); add(0);//
      for(int i=1,x,s=0;i<=n;i++)
        {
          x=rd(); a[i]=x; s^=x;
          pr[i]=max(pr[i-1],query(s)); add(s);
        }
      cnt=0; memset(c,0,sizeof c); add(0);
      for(int i=n,s=0;i;i--)
        {
          s^=a[i];
          sc[i]=max(sc[i+1],query(s)); add(s);
        }
      int ans=0;
      for(int i=1;i<n;i++)ans=max(ans,pr[i]+sc[i+1]);
      printf("%d
    ",ans);
      return 0;
    }
  • 相关阅读:
    动手动脑
    选课1.0
    四则运算
    JAVA异常处理机制资料整理
    JAVA学习日报(快乐作业) 10.27
    JAVA学习日报(快乐作业) 10.20
    JAVA学习日报 9/30
    JAVA学习日报 9/28
    JAVA学习日报 9/27
    JAVA学习日报 9/26
  • 原文地址:https://www.cnblogs.com/Zinn/p/9804379.html
Copyright © 2011-2022 走看看