一 原题
Adrian Vladu -- 2005
Farmer John is stuck with another problem while feeding his cows. All of his N (1 ≤ N ≤ 100,000) cows (numbered 1..N) are lined up in front of the barn, sorted by their rank in their social hierarchy. Cow #1 has the highest rank; cow #N has the least rank. Every cow had additionally been assigned a non-unique integer number in the range 0..(221 - 1).
Help FJ choose which cows will be fed first by selecting a sequence of consecutive cows in the line such that the bitwise "xor" between their assigned numbers has the maximum value. If there are several such sequences, choose the sequence for which its last cow has the highest rank. If there still is a tie, choose the shortest sequence.
TIME LIMIT: 0.5 sec
PROGRAM NAME: cowxor
INPUT FORMAT
- Line 1: A single integer N
- Lines 2..N+1: N integers ranging from 0 to 221 - 1, representing the cows' assigned numbers. Line j describes cow of social hierarchy j-1.
SAMPLE INPUT (file cowxor.in)
5 1 0 5 4 2
INPUT DETAILS:
There are 5 cows. Cow #1 had been assigned with 1; cow #2 with 0; cow #3 with 5; cow #4 with 4; cow #5 with 2.OUTPUT FORMAT
- Line 1: Three space-separated integers, respectively: the maximum requested value, the position where the sequence begins, the position where the sequence ends.
SAMPLE OUTPUT (file cowxor.out)
6 4 5
OUTPUT DETAILS:
4 xor 2 = 6 (001) xor (010) = (011)
二 分析
三 代码
/*
ID:maxkibb3
LANG:C++
PROB:cowxor
*/
#include<cstdio>
#include<bitset>
const int MAX = 1e5 + 5;
int N, Arr[MAX], Xor[MAX], Trie_size;
struct Node {
int val, left, right;
Node() { val = 0; left = right = -1; }
Node(int _v) : val(_v) { left = right = -1; }
}Trie[MAX * 5];
void create(int _v, int _f) {
if(_v) Trie[_f].right = Trie_size;
else Trie[_f].left = Trie_size;
Trie[Trie_size++] = Node(_v);
}
void insert(int _v, int _i) {
std::bitset<21> bits(_v);
int root = 0;
for(int i = 20; i >= 0; i--) {
if(bits[i]) {
if(Trie[root].right == -1)
create(1, root);
root = Trie[root].right;
}
else {
if(Trie[root].left == -1)
create(0, root);
root = Trie[root].left;
}
}
create(_i, root);
}
int find(int _v) {
std::bitset<21> bits(_v);
int root = 0;
for(int i = 20; i >= 0; i--) {
if(bits[i]) {
if(Trie[root].left != -1)
root = Trie[root].left;
else
root = Trie[root].right;
}
else {
if(Trie[root].right != -1)
root = Trie[root].right;
else
root = Trie[root].left;
}
}
return Trie[Trie[root].right].val;
}
int main() {
freopen("cowxor.in", "r", stdin);
freopen("cowxor.out", "w", stdout);
scanf("%d", &N);
Trie[Trie_size++] = Node(0);
for(int i = 1; i <= N; i++)
scanf("%d", &Arr[i]);
int ans = Arr[1], l = 1, r = 1;
for(int i = 1; i <= N; i++) {
Xor[i] = Xor[i - 1] ^ Arr[i];
insert(Xor[i], i);
int idx = find(Xor[i]);
int tmp = Xor[idx] ^ Xor[i];
if(tmp > ans) ans = tmp, l = idx + 1, r = i;
}
printf("%d %d %d\n", ans, l, r);
return 0;
}
USER: Qi Shen [maxkibb3] TASK: cowxor LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 8664 KB] Test 2: TEST OK [0.000 secs, 8664 KB] Test 3: TEST OK [0.000 secs, 8664 KB] Test 4: TEST OK [0.000 secs, 8664 KB] Test 5: TEST OK [0.028 secs, 8928 KB] Test 6: TEST OK [0.084 secs, 9984 KB] Test 7: TEST OK [0.112 secs, 9324 KB] Test 8: TEST OK [0.140 secs, 11172 KB] Test 9: TEST OK [0.084 secs, 8664 KB] Test 10: TEST OK [0.056 secs, 8664 KB] Test 11: TEST OK [0.056 secs, 8664 KB] Test 12: TEST OK [0.126 secs, 10116 KB] Test 13: TEST OK [0.042 secs, 8664 KB] Test 14: TEST OK [0.098 secs, 8664 KB] Test 15: TEST OK [0.308 secs, 11700 KB] Test 16: TEST OK [0.294 secs, 11700 KB] Test 17: TEST OK [0.294 secs, 11700 KB] Test 18: TEST OK [0.210 secs, 10908 KB] Test 19: TEST OK [0.028 secs, 8928 KB] Test 20: TEST OK [0.000 secs, 8664 KB] All tests OK.
/*
ID:maxkibb3
LANG:C++
PROB:cowxor
*/
#include<cstdio>
#include<bitset>
#include<cstring>
#include<map>
#define left(x) ((x << 1) + 1)
#define right(x) ((x << 1) + 2)
const int MAX = 1e5 + 5;
int N, Xor[MAX];
bool Trie[1 << 22];
std::map<int, int> M;
void insert(int _v, int _i) {
std::bitset<21> bits(_v);
int root = 0;
for(int i = 20; i >= 0; i--) {
if(bits[i]) root = right(root);
else root = left(root);
if(!Trie[root]) Trie[root] = 1;
}
std::map<int, int>::iterator it = M.find(root);
if(it == M.end()) M.insert(std::make_pair(root, _i));
else it->second = _i;
}
int find(int _v) {
std::bitset<21> bits(_v);
int root = 0, next;
for(int i = 20; i >= 0; i--) {
if(bits[i]) {
next = left(root);
if(Trie[next]) root = next;
else root = right(root);
}
else {
next = right(root);
if(Trie[next]) root = next;
else root = left(root);
}
}
std::map<int, int>::iterator it = M.find(root);
if(it != M.end()) return it->second;
}
int main() {
freopen("cowxor.in", "r", stdin);
freopen("cowxor.out", "w", stdout);
scanf("%d", &N);
for(int i = 1; i <= N; i++) {
int tmp;
scanf("%d", &tmp);
Xor[i] = Xor[i - 1] ^ tmp;
}
int ans = Xor[1], l = 1, r = 1;
for(int i = 1; i <= N; i++) {
insert(Xor[i], i);
int idx = find(Xor[i]);
int tmp = Xor[idx] ^ Xor[i];
if(tmp > ans) ans = tmp, l = idx + 1, r = i;
}
printf("%d %d %d\n", ans, l, r);
return 0;
}