bzoj 3166: [Heoi2013]Alo 可持久化trie
2013-10-31 19:27
561 查看
题意 : 选取一个区间 区间中的第二大的那个数 可以跟 区间中的任意一个数 进行 异或得到一个区间内的最大的值。
问任意选取区间,问最大的那个 异或的值是多少。 ?
枚举每个数是 区间中的 第二大的值, 找到 可行的区间,可行区间就是 : [ 左边第二个比这个大的数的下标 +1,右边第二个比这个数大的数的下标-1];
然后 可持久化 trie ,求 区间 对于 a 的最大的异或值。
怎么求 这个区间 ?
维护下标即可。 排序后 ,从 右往左添加 下标的值, 这样就保证了 ,已经添加进去的值一定比当前的值大, 这样,我们只要求比当前这个点的原来的下标的 值的 upper_bound 的 upper_bound 的值就是 右边第二大的值下标。
同理 左边的也可求。
问任意选取区间,问最大的那个 异或的值是多少。 ?
枚举每个数是 区间中的 第二大的值, 找到 可行的区间,可行区间就是 : [ 左边第二个比这个大的数的下标 +1,右边第二个比这个数大的数的下标-1];
然后 可持久化 trie ,求 区间 对于 a 的最大的异或值。
怎么求 这个区间 ?
维护下标即可。 排序后 ,从 右往左添加 下标的值, 这样就保证了 ,已经添加进去的值一定比当前的值大, 这样,我们只要求比当前这个点的原来的下标的 值的 upper_bound 的 upper_bound 的值就是 右边第二大的值下标。
同理 左边的也可求。
/************************************************************** Problem: 3166 User: OceanLight Language: C++ Result: Accepted Time:892 ms Memory:229988 kb ****************************************************************/ #include <vector> #include <list> #include <map> #include <set> #include <deque> #include <stack> #include <cstring> #include <bitset> #include <algorithm> #include <functional> #include <numeric> #include <utility> #include <sstream> #include <iostream> #include <iomanip> #include <cstdio> #include <cmath> #include <cstdlib> #include <ctime> #include <assert.h> #include <queue> #define REP(i,n) for(int i=0;i<n;i++) #define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++) #define ALLL(x) x.begin(),x.end() #define SORT(x) sort(ALLL(x)) #define CLEAR(x) memset(x,0,sizeof(x)) #define FILLL(x,c) memset(x,c,sizeof(x)) using namespace std; const double eps = 1e-9; #define LL long long #define pb push_back const int maxn = 310000; int num[maxn]; struct Node{ Node *s[2]; int sum; }nodes[maxn*60]; Node *root[maxn],*null; int C; int n; void init(){ C=0; root[0] = null = &nodes[C++]; null->s[0] = null->s[1] = null; null->sum = 0; } Node *insert(int v,int d,Node *root){ Node *rt = &nodes[C++]; rt->s[0] = root->s[0]; rt->s[1] = root->s[1]; rt->sum = root->sum+1; if(d<0)return rt; int p = (v>>d)&1; rt->s[p] = insert(v,d-1,root->s[p]); return rt; } int query(int v,int d,Node *rt1,Node *rt2){ if(d<0)return 0; int p = (v>>d)&1; if(rt2->s[p^1]->sum - rt1->s[p^1]->sum){ // cout << d << " dd " << (1<<d)<< endl; return (1<<d)+query(v,d-1,rt1->s[p^1],rt2->s[p^1]); } return query(v,d-1,rt1->s[p],rt2->s[p]); } const int K = 31; int l[maxn],r[maxn],l2[maxn],r2[maxn]; void solve(){ init(); for(int i =1;i<=n;i++){ // cout << num[i]<< endl; root[i] = insert(num[i],K,root[i-1]); } int ans = 0 ; for(int i=1;i<=n;i++){ if(r2[i] == n && l2[i] == 0) continue; int ret = query(num[i],K,root[l[i]],root[r[i]-1]); // cout << ret << " "<< i << " "<< l[i] << " " << r[i]-1<<endl; ans = max(ret,ans); } cout << ans <<endl; } struct S{ int num; int id; bool operator<(const S &b)const { return num< b.num; } }s[maxn]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&s[i].num); num[i] = s[i].num; s[i].id = i; } sort(s+1,s+n+1); multiset<int>st; multiset<int>::iterator it,it2; st.insert(n+1); st.insert(n+1); st.insert(0); st.insert(0); for(int i=n;i>0;i--){ st.insert(s[i].id); //cout << s[i].id<<endl; it2 = it = st.lower_bound(s[i].id); // cout << " ** "<< *it<<endl; it++; r2[s[i].id] = *it; it++; it2--; l2[s[i].id] = *it2; it2--; r[s[i].id] = *it; l[s[i].id] = *it2; //cout << s[i].id << " " << *it<< " "<<*it2<<endl; } solve(); return 0; }
相关文章推荐
- bzoj 3166 [Heoi2013]Alo 可持久化trie 线段树
- 【bzoj3166】【HEOI2013】【Alo】【set+可持久化trie】
- 【可持久化Trie】【set】bzoj3166 [Heoi2013]Alo
- 【ChairTrie】【bzoj 3166】: [Heoi2013]Alo
- BZOJ3166 [Heoi2013]Alo 可持久化Trie
- bzoj 3166: [Heoi2013]Alo (可持久化trie+线段树)
- [BZOJ3166][Heoi2013]Alo(可持久化线段树+可持久化tire树)
- bzoj3166: [Heoi2013]Alo
- 【BZOJ】【3166】【HEOI2013】Alo
- BZOJ3166: [Heoi2013]Alo
- BZOJ3166 [Heoi2013]Alo 【可持久化trie树 + 二分 + ST表】
- [可持久化字典树 set] BZOJ 3166 [Heoi2013]Alo
- BZOJ 3166: [Heoi2013]Alo|可持久化Trie树
- [BZOJ3166][HEOI2013]Alo-可持久化字典树
- 3166: [Heoi2013]Alo 可持久化trie
- 【bzoj3166】[Heoi2013]Alo 可持久化Trie树+STL-set
- BZOJ 3166 [Heoi2013]Alo
- [BZOJ3166][Heoi2013]Alo 可持久化Trie树
- bzoj 3166 [Heoi2013]Alo 可持久化字典树
- bzoj 3166: [Heoi2013]Alo