标签:
给n个数, 让你找出一个前缀和一个后缀, 它们异或完以后最大, 前缀和后缀都是异或得来的, 可以为空, 为空时按0算。前缀后缀不可覆盖。
这题好神, 竟然是Trie树...
首先将所有数的异或算出来作为初始的后缀, 初始前缀为0。 然后往字典树里插入前缀, 在对后缀进行查找, 查找时, 从高位往低位找, 如果后缀的第i位为0, 那么就找字典树里这一位有没有1, 有1就往1的那一条路找,没有就只能往0那一条路找。
具体看代码。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; struct Trie { Trie *next[2]; Trie() { next[0] = next[1] = NULL; } }; ll num[100005], top = 40; Trie *root = new Trie(); void add(ll val) { Trie *p = root; for(int i = top-1; i>=0; i--) { int tmp = val>>i&1; if(!p->next[tmp]) p->next[tmp] = new Trie(); p = p->next[tmp]; } } ll query(ll val) { Trie *p = root; ll ret = 0; for(int i = top-1; i>=0; i--) { int tmp = val>>i&1; if(p->next[tmp^1]) { ret |= 1LL<<i; tmp ^=1; } p = p->next[tmp]; } return ret; } int main() { int n; ll prefix = 0, suffix = 0, ans = 0; cin>>n; for(int i = 1; i<=n; i++) { cin>>num[i]; suffix^=num[i]; } for(int i = 1; i<=n+1; i++) { add(prefix); ans = max(ans, query(suffix)); if(i<=n) { prefix^=num[i]; suffix^=num[i]; } } cout<<ans<<endl; return 0; }
codeforces 282E. Sausage Maximization Trie
标签:
原文地址:http://www.cnblogs.com/yohaha/p/5083625.html