题意:摘自NOCOW翻译(http://www.nocow.cn/index.php/Translate:USACO/cowxor)
描述
农民约翰在喂奶牛的时候被另一个问题卡住了。他的所有N(1 <= N <= 100,000)个奶牛在他面前排成一行(按序号1..N的顺序),按照它们的社会等级排序。奶牛#1有最高的社会等级,奶牛#N最低。每个奶牛同时被指定了一个不唯一的附加值,这个数在0..2^21 - 1的范围内。
帮助农民约翰找出应该从哪一头奶牛开始喂,使得从这头奶牛开始的一个连续的子序列上,奶牛的附加值的异或最大。
如果有多个这样的子序列,选择结尾的奶牛社会等级最高的。如果还不唯一,选择最短的。
[编辑]格式
PROGRAM NAME: cowxor
INPUT FORMAT:
(file cowxor.in)
INPUT FORMAT
第1行:一个单独的整数N。
第2到N + 1行:N个0..2^21 - 1之间的整数,代表每头奶牛的被赋予的数。第j行描述了社会等级j - 1的奶牛。
OUTPUT FORMAT:
(file cowxor.out)
第 1 行: 3个空格隔开的整数,分别为:最大的异或值,序列的起始位置、终止位置。 时限0.5秒
[编辑]SAMPLE INPUT
5 1 0 5 4 2
[编辑]SAMPLE OUTPUT
6 4 5
[编辑]样例输出说明
最大异或值为6,从第4个开始喂,到第5个结束。
4 异或 2 = 6
(100) 异或 (010) = (110)
解题思路:
代码:
/*
ID: zc.rene1
LANG: C
PROG: cowxor
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 700000
typedef struct
{
int value;
int index;
int sub[2];
}node;
node nodes[SIZE];
int node_num;
int N;
int root;
int GetBit(int x, int index)
{
return (x & (1 << index)) >> index;
}
void insert(int value, int index)
{
int i, j, current;
if (node_num == 0)
{
memset(nodes + node_num, -1, sizeof(node));
node_num++;
root = 0;
}
current = root;
for (i=20; i>=0; i--)
{
j = GetBit(value, i);
if (nodes[current].sub[j] == -1)
{
memset(nodes + node_num, -1, sizeof(node));
nodes[current].sub[j] = node_num;
node_num++;
}
current = nodes[current].sub[j];
}
nodes[current].value = value;
nodes[current].index = index;
}
int FindMaxIndex(int value)
{
int i, j, current = root;
for (i=20; i>=0 && current != -1; i--)
{
j = GetBit(value, i);
if (nodes[current].sub[(j + 1) % 2] != -1)
{
current = nodes[current].sub[(j + 1) % 2];
}
else
{
current = nodes[current].sub[j];
}
}
return current;
}
int main(void)
{
FILE *fin, *fout;
int i, j, num, result;
int max = -1, max_i, max_j;
fin = fopen("cowxor.in", "r");
fout = fopen("cowxor.out", "w");
node_num = 0;
insert(0, 0);
result = 0;
fscanf(fin, "%d", &N);
for (i=1; i<=N; i++)
{
fscanf(fin, "%d", &num);
result ^= num;
j = FindMaxIndex(result);
if (j != -1 && (result ^ nodes[j].value) > max)
{
max = result ^ nodes[j].value;
max_i = nodes[j].index + 1;
max_j = i;
}
insert(result, i);
}
fprintf(fout, "%d %d %d\n", max, max_i, max_j);
return 0;
}