LightOJ - 1269 Consecutive Sum

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Leon_liuqinburen/article/details/78264653

题目链接:https://vjudge.net/problem/LightOJ-1269

利用前缀异或和的思想加01字典树


#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 50000 + 10;

struct Trie
{
    int ch[32 * MAXN][2];               //节点的边信息
    int num[32 * MAXN];                 //节点存储值的个数
    LL value[32 * MAXN];                //节点存储的值
    int node_cnt;                       //树中当前节点个数

    void init()                  //树清空
    {
        node_cnt = 1;
        memset(ch[0],0,sizeof(ch));
        memset(num, 0, sizeof(num));
    }

    void Insert(LL x)            //在字典树中插入 X
    {
        //和一般字典树的操作相同 将X的二进制插入到字典树中
        int cur = 0;
        for(int i = 32; i >= 0; --i)
        {
            int idx = (x >> i) & 1;
            if(!ch[cur][idx])
            {
                memset(ch[node_cnt],0,sizeof(ch[node_cnt]));
                ch[cur][idx] = node_cnt;
                value[node_cnt++] = 0;
            }
            cur = ch[cur][idx];
            num[cur]++;
        }
        value[cur] = x;             //最后的节点插入value
    }

    void update(LL x, int d)   //更新x的个数  d为浮动值
    {
        int cur = 0;
        for(int i = 32 ; i >= 0 ; i--)
        {
            int idx = (x >> i) & 1;
            cur = ch[cur][idx];
            num[cur] += d;
        }
    }

    LL Query(LL x, int dir)               //在字典树中查找和X异或的最大值\最小值的元素Y 返回Y的值
    {
        int cur = 0;
        for(int i = 32; i >= 0; --i)
        {
            int idx = (x >> i) & 1;
            if(ch[cur][idx ^ dir] && num[ch[cur][idx ^ dir]]) cur = ch[cur][idx ^ dir];
            else cur = ch[cur][idx ^ !dir];
        }
        return value[cur];
    }
};
LL num[100005];
LL xors[100005];
Trie ts;
int main()
{
    int T, CAS = 0;
    scanf("%d", &T);
    while(T--)
    {
        int n;
        scanf("%d", &n);
        ts.init();

        for(int i = 1 ; i <= n ; i++)
        {
            scanf("%lld", &num[i]);
            xors[i] = xors[i - 1] ^ num[i];
        }
        ts.Insert(0); ///任何值与0异或都是它本身
        LL mx = 0;
        LL mi = 1e12;
        for(int i = 1 ; i <= n ; i++)
        {
            LL t0 = ts.Query(xors[i], 0); ///找异或最小值
            LL t1 = ts.Query(xors[i], 1); ///找异或最大值
            mi = min(mi, t0 ^ xors[i]);
            mx = max(mx, t1 ^ xors[i]);
            ts.Insert(xors[i]);
//            printf("%lld %lld##\n", mx, mi);
        }
        printf("Case %d: %lld %lld\n", ++CAS, mx, mi);
    }
}


猜你喜欢

转载自blog.csdn.net/Leon_liuqinburen/article/details/78264653