zoukankan      html  css  js  c++  java
  • BZOJ4260 Codechef REBXOR

    题意:

    给出一个含(N)个元素的数组(A),下标从(1)开始,请找出下列式子的最大值:

    [(A[l_1]oplus A[l_1+1]oplusdotsoplus A[r_1])+(A[l_2]oplus A[l_2+1]oplusdots A[r_2]) ]

    其中(1leq l_1 leq r_1 < l_2 leq r_2leq N)

    思路:

    01字典树。当然会了一点简单的题,这个还是没有一点思路,之前的都是跑一个数的最大值,这里是区间。这里用到了简单的异或性质

    • (0oplus a = a, aoplus a = 0)

    所以这里用到了前缀异或和(pre[i]),后缀异或和(suf[i])

    (pre[i]oplus pre[j] = a[i+1]oplus a[i+2]oplusdotsoplus a[j], i < j),后缀同理

    所以我们可以利用(dp)思想,(dp[i])表示前(i)个数的任意区间最大值。

    通过查询(pre[i])来获得任意区间的最大值---->利用上面的性质。

    每次再把(pre[i])插入到字典树中。

    对于后缀,为了使区间不相交,这里跑(suf[i])包含第(i)个数,所以为(Query(suf[i])+dp[i-1]),让前缀不包含第(i)个数。

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 400010;
    const int inf = 0X3f3f3f3f;
    const long long INF = 0x3f3f3f3f3f3f3f3f;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    const int mod = 1000000007;
    typedef long long ll;
    
    int n;
    int a[N];
    int pre[N], suf[N];
    int dp[N];
    int tri[32 * N][2];
    int val[32 * N];
    int tot;
    
    void init() {
        memset(tri, 0, sizeof(tri));
        memset(val, 0, sizeof(val));
        tot = 1;
    }
    
    void Insert(int x) {
        int u = 0;
        for (int i = 31; i >= 0; i--) {
            int bit = (x & (1 << i)) ? 1 : 0;
            if (!tri[u][bit])
                tri[u][bit] = tot++;
            u = tri[u][bit];
        }
        val[u] = x;
    }
    
    int Query(int x) {
        int u = 0;
        for (int i = 31; i >= 0; i--) {
            int bit = (x & (1 << i)) ? 1 : 0;
            if (tri[u][bit ^ 1])
                u = tri[u][bit ^ 1];
            else
                u = tri[u][bit];
        }
        return x ^ val[u];
    }
    
    int main() {
        while(~scanf("%d", &n)) {
            init();
            for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
            pre[0] = suf[n + 1] = 0;
            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], Query(pre[i]));
                Insert(pre[i]);
            }
            init();
            Insert(suf[n + 1]);
            int ans = -1;
            for (int i = n; i >= 1; i--) {
                ans = max(ans, Query(suf[i]) + dp[i - 1]);
                Insert(suf[i]);
            }
            printf("%d
    ", ans);
        }
    }
    
    
  • 相关阅读:
    CF 319C
    日常---区域赛临近
    poj 3728 The merchant 倍增lca求dp
    zoj 3742 Delivery 好题
    zoj 3717 Balloon 2-sat
    CF 163E. e-Government ac自动机+fail树+树状数组
    CF 335B
    hdu 4739 状压DP
    hdu 4738 桥
    Hibernate中的继承映射
  • 原文地址:https://www.cnblogs.com/ACMerszl/p/12225784.html
Copyright © 2011-2022 走看看