LightOJ 1269 - Consecutive Sum(字典树)

题目链接:LightOJ 1269 - Consecutive Sum

题目大意:给定一个序列,选定一段区间的亦或和,输出最大和最小。

解题思路:最大很简单,对所有前缀建立字典树,然后尽量往反向走;最小则需要往正向走,并且向正向走的时候要扣

除自己本身。

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 50005 * 32;
const int sigma_size = 2;

struct Tire {
    int sz;
    int g[maxn][sigma_size];
    int c[maxn];

    void init();
    void insert(int s);
    int findMax(int s);
    int findMin(int s);
}T;

int N, A[maxn];

int main () {
    int cas, x;
    scanf("%d", &cas);
    for (int kcas = 1; kcas <= cas; kcas++) {
        T.init();
        scanf("%d", &N);
        for (int i = 1; i <= N; i++) {
            scanf("%d", &x);
            A[i] = A[i-1] ^ x;
        }

        for (int i = 0; i <= N; i++)
            T.insert(A[i]);

        int ansMax = 0, ansMin = (1<<31)-1;
        for (int i = 0; i <= N; i++) {
            ansMax = max(ansMax, T.findMax(A[i]));
            ansMin = min(ansMin, T.findMin(A[i]));
        }
        printf("Case %d: %d %d\n", kcas, ansMax, ansMin);
    }
    return 0;
}

void Tire::init() {
    sz = 1;
    c[0] = 0;
    memset(g[0], 0, sizeof(g[0]));
}

int Tire::findMin(int s) {
    int ret = 0, u = 0;
    for (int i = 30; i >= 0; i--) {
        int v = (s>>i) & 1;

        if (g[u][v] == 0 || (g[u][v^1] && c[g[u][v]] < 2)) {
            v = v ^ 1;
            ret |= (1<<i);
        } 

        u = g[u][v];
    }
    return ret;
}

int Tire::findMax(int s) {
    int ret = 0, u = 0;

    for (int i = 30; i >= 0; i--) {
        int v = ((s>>i)&1)^1;

        if (g[u][v])
            ret |= (1<<i);
        else
            v = v ^ 1;
        u = g[u][v];
    }
    return ret;
}

void Tire::insert(int s) {
    int u = 0;

    for (int i = 30; i >= 0; i--) {
        int v = (s>>i) & 1;

        if (g[u][v] == 0) {
            c[sz] = 0;
            memset(g[sz], 0, sizeof(g[sz]));
            g[u][v] = sz++;
        }

        u = g[u][v];
        c[u]++;
    }
}
时间: 2024-08-03 11:23:56

LightOJ 1269 - Consecutive Sum(字典树)的相关文章

HDU 4825 Xor Sum 字典树+位运算

点击打开链接 Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 291    Accepted Submission(s): 151 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus

2014百度之星第三题Xor Sum(字典树+异或运算)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 4445    Accepted Submission(s): 652 Problem Description Zeus 和 Prometheus 做了一个游戏.Prometheus 给 Zeus 一个集合,集合中包括了N个正整数.随后 Prometheus 将向 Ze

Xor Sum(字典树加贪心)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 457    Accepted Submission(s): 231 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeu

Codeforces Round #482 (Div. 2)D. Kuro and GCD and XOR and SUM+字典树

题目链接:D. Kuro and GCD and XOR and SUM 题意:两种操作:第一种给数组添加一个数,第二种输入x,k,s,要求从数组中找到一个数v,要求k能整除gcd(k,v);并且v<=s-x,然后异或v与k的异或值最大. 题解:对与k大于1的情况我们暴力枚举过去,k为1的特殊处理建一颗字典树,如果可以的满足条件的话,每次取值时往相反方向取. 1 #include<bits/stdc++.h> 2 #include <iostream> 3 #include

hdu 4825 xor sum(字典树+位运算)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 4144    Accepted Submission(s): 1810 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Ze

HDU--4825 Xor Sum (字典树)

题目链接:HDU--4825 Xor Sum mmp sb字典树因为数组开的不够大一直wa 不是报的 re!!! 找了一下午bug 草 把每个数转化成二进制存字典树里面 然后尽量取与x这个位置上不相同的 先来一个最原始的代码写的跟屎一样的 #include<iostream> #include<cstring> #include<algorithm> #include<string.h> #include<stdio.h> #include<

hdu 4825 Xor Sum(字典树)

Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大.Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助.你能证明人类的智慧么? Input 输入包含若干组测试数据,每组测试数据

1269 - Consecutive Sum

   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 64 MB Little Jimmy is learning how to add integers. As in decimal the digits are 0 to 9, it makes a bit hard for him to understand the summation of all pair of digits. Since addi

字典树经典问题

HDU4852 Xor Sum  字典树 题意 Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大,输出K(共有t组样例,(T < 10),N,M(<1=N,M<=100000)) 分析 将每个数插入到线段树后,对于每个s贪心的在字典树上走走即可