Consecutive Sum
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 addition of numbers requires the knowledge of adding digits. So, his mother gave him a software that can convert a decimal integer to its binary and a binary to its corresponding decimal. So, Jimmy’s idea is to convert the numbers into binaries, and then he adds them and turns the result back to decimal using the software. It’s easy to add in binary, since you only need to know how to add (0, 0), (0, 1), (1, 0), (1, 1). Jimmy doesn’t have the idea of carry operation, so he thinks that
1 + 1 = 0
1 + 0 = 1
0 + 1 = 1
0 + 0 = 0
Using these operations, he adds the numbers in binary. So, according to his calculations,
3 (011) + 7 (111) = 4 (100)
Now you are given an array of n integers, indexed from 0 to n-1, you have to find two indices i j in the array (0 ≤ i ≤ j < n), such that the summation (according to Jimmy) of all integers between indices i and j in the array, is maximum. And you also have to find two indices, p q in the array (0 ≤ p ≤ q < n), such that the summation (according to Jimmy) of all integers between indices p and **q **in the array, is minimum. You only have to report the maximum and minimum integers.
Input
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case starts with a line containing an integer n (1 ≤ n ≤ 50000). The next line contains n space separated non-negative integers, denoting the integers of the given array. Each integer fits into a 32 bit signed integer.
Output
For each case, print the case number, the maximum and minimum summation that can be made using Jimmy’s addition.
- 输入
2
5
6 8 2 4 2
5
3 8 2 6 5 - 输出
Case 1: 14 2
Case 2: 15 1
LightOJ-1269
代码:
#include<cstdio>
#include<set>
#include<algorithm>
#include<iostream>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e5+10;
int son[N*32][2],idx;
typedef long long LL;
void insert(LL t,int v)
{
int p = 0;
for(int i=31;i>=0;i--)
{
int u = t>>i&1;
if(son[p][u] == -1)
son[p][u] = ++idx;
p = son[p][u];
}
return ;
}
LL query(LL t) //先判断是否存在不同,在没有的情况下再找相同的
{
LL ans = t;
int p = 0;
for(int i=31;i>=0;i--)
{
int u = t>>i&1;
if(son[p][!u]!=-1)
{
ans^=((!u)<<i);
p=son[p][!u];
}
else
{
ans^=((u)<<i);
p=son[p][u];
}
}
return ans;
}
LL query1(LL t) //先判断是否存在相同,在没有的情况下使用不同
{
LL ans = t;
int p = 0;
for (int i = 31; i >= 0; i--)
{
int u = t >> i & 1;
if (son[p][u] != -1)
{
ans ^= ((u) << i);
p = son[p][u];
}
else
{
ans ^= ((!u) << i);
p = son[p][!u];
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
for(int liuzhuo=1;liuzhuo<=T;liuzhuo++)
{
idx = 0;
memset(son,-1,sizeof son); //初始化
insert(0,1); //插入0
LL res = -1e9;
LL res1 = INF;
LL sum = 0;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
LL t;
scanf("%lld",&t);
sum^=t;
res1 = min(res1,query1(sum)); //在计算最小值的时候要避免判断自己,使最小值变成0,所以在插入之前先进行判断
insert(sum,1);
res = max(res,query(sum));
}
printf("Case %d: %lld %lld\n",liuzhuo,res,res1);
}
}