• BZOJ 4260: Codechef REBXOR(01trie+思维)


    求两个不相交区间异或和的和最大.

    设l[i]是1~i一段区间的最大异或和,r[i]是i~n一段区间的最大异或和,题意就是求max(l[i]+r[i+1]);

    那么只要求l,r数组。

    设num数组是个前缀异或和,根据异或的性质,我们要求i~j的异或和就是num[i]^num[j],所以对于l数组,我们要求出max(num[i]^num[j]),r数组用后缀异或和同理.

    l[i]=max(l[i-1],find(num[i-1]^a[i])) l[i-1]表示区间不包括i,否则就是用find函数找区间包括i的值.find函数就是再trie树上尽量往相反的方向爬。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <queue>
     7 #include <map>
     8 #define ll long long
     9 #define out(a) printf("%d",a)
    10 #define writeln printf("
    ")
    11 const int N=4e5+50;
    12 const int MOD=1e9+7;
    13 using namespace std;
    14 int n;
    15 int tot=1;
    16 int a[N];
    17 int num[N],l[N],r[N];
    18 int trie[N*31][2];
    19 int ans;
    20 int read()
    21 {
    22     int s=0,t=1; char c;
    23     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
    24     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
    25     return s*t;
    26 }
    27 ll readl()
    28 {
    29     ll s=0,t=1; char c;
    30     while (c<'0'||c>'9'){if (c=='-') t=-1; c=getchar();}
    31     while (c>='0'&&c<='9'){s=s*10+c-'0'; c=getchar();}
    32     return s*t;
    33 }
    34 void insert(int x)
    35 {
    36     int u=1;
    37     for (int i=31;i>=0;i--){
    38       int c=((1<<i)&x)>0;
    39       if (!trie[u][c]) trie[u][c]=++tot;
    40       u=trie[u][c];
    41     }
    42 }
    43 int find(int x)
    44 {
    45     int u=1,res=0;
    46     for (int i=31;i>=0;i--){
    47       int c=((1<<i)&x)>0;
    48       if (trie[u][1-c]) u=trie[u][1-c],res+=(1<<i);
    49       else u=trie[u][c];
    50     }
    51     return res;
    52 }
    53 int main()
    54 {
    55     n=read();
    56     for (int i=1;i<=n;i++){
    57       a[i]=read();
    58       insert(num[i-1]);
    59       num[i]=num[i-1]^a[i];
    60       l[i]=max(l[i-1],find(num[i]));
    61     }
    62     memset(trie,0,sizeof(trie));
    63     for (int i=n;i;i--){
    64       insert(num[i+1]);
    65       num[i]=num[i+1]^a[i];
    66       r[i]=max(r[i+1],find(num[i]));
    67       ans=max(ans,l[i]+r[i+1]);
    68     }
    69     out(ans);
    70     return 0;
    71 }
    72     
    73     
    View Code
  • 相关阅读:
    jquery 序列化form表单
    nginx for windows 安装
    nodejs idea 创建项目 (一)
    spring 配置 shiro rememberMe
    idea 2018 解决 双击shift 弹出 search everywhere 搜索框的方法
    redis 在windows 集群
    spring IOC控制反转和DI依赖注入
    redis 的安装
    shiro 通过jdbc连接数据库
    handlebars的用法
  • 原文地址:https://www.cnblogs.com/Kaleidoscope233/p/9563206.html
Copyright © 2020-2023  润新知