zoukankan      html  css  js  c++  java
  • 两区间异或和最大

    https://blog.csdn.net/zuzhiang/article/details/79877109

    题意:给xi你 n 个数,让你求两个不相交的区间元素异或后的和的最大值。本题中 n 的上限是  4*10^5.

    解法:求出前缀异或和和后缀异或和,dp【i】表示前i个数任意区间的最大异或和。

    根据性质异或和性质dp【i】异或dp【j】相同部分会抵消,可以根据递推求出dp【i】

    转化为dp【i-1】+ suf【i】最大值,可以防止区间重叠。

    #include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <stdio.h>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <string.h>
    #include <vector>
    #define ME(x , y) memset(x , y , sizeof(x))
    #define SF(n) scanf("%d" , &n)
    #define rep(i , n) for(int i = 0 ; i < n ; i ++)
    #define INF  0x3f3f3f3f
    #define mod 1000000007
    #define PI acos(-1)
    using namespace std;
    typedef unsigned long long ll ;
    const int N = 400009;
    int tree[N*32][2] , vis[N*32] , tol;
    int a[N];
    int pre[N] , suf[N];
    int dp[N] ;
    
    void insert(int x)
    {
        int u = 0 ;
        for(int i = 31 ; i >= 0 ; i--)
        {
            int p = (x >> i) & 1 ;
            if(!tree[u][p]) tree[u][p] = ++tol ;
            u = tree[u][p];
        }
        vis[u] = x ;
    }
    
    int research(int x)
    {
        int u = 0 ;
        for(int i = 31 ; i >= 0 ; i--)
        {
            int p = (x >> i) & 1 ;
            if(tree[u][p^1]) u = tree[u][p^1];
            else u = tree[u][p];
        }
        return x ^ vis[u];
    }
    
    int main()
    {
        int n ;
        scanf("%d" , &n);
        for(int i = 1 ; i <= n ; i++)
        {
            scanf("%d" , &a[i]);
        }
        for(int i = 1 ; i <= n ; i++) pre[i] = pre[i-1] ^ a[i];//前缀异或和
        for(int i = n ; i >= 1 ; i--) suf[i] = suf[i+1] ^ a[i];
        insert(pre[0]);
        for(int i = 1 ; i <= n ; i++)
        {
            dp[i] = max(dp[i-1] , research(pre[i]));//求前i个数中任意区间异或最大
            insert(pre[i]);
        }
        tol = 0 ;
        memset(vis , 0 , sizeof(vis));
        memset(tree , 0 , sizeof(tree));
        int ans = -INF;
        insert(suf[n+1]);
        for(int i = n ; i >= 1 ; i--)
        {
            ans = max(ans , research(suf[i]) + dp[i-1]);//后缀异或和+前缀异或和最大
            insert(suf[i]);
        }
        cout << ans << endl ;
    
        return 0;
    }
    
  • 相关阅读:
    redux的理解
    跨域的三种解决方案
    HTTP缓存字段总结
    src属性与浏览器渲染
    ES6之promise原理
    http header Content-Type之常用三种
    用css实现正方形div
    js判断数据类型
    react中PureComponent浅对比策略
    React中自己实现选项卡动画
  • 原文地址:https://www.cnblogs.com/nonames/p/12222746.html
Copyright © 2011-2022 走看看