奶牛异或(01字典树)
奶牛异或
https://ac.nowcoder.com/acm/problem/22998
题意:
让你找一个连续区间异或和最大,如果有相同的,则输出断点较小的。
题解:
01字典树,利用前缀和的思想进行求解,我们在插入前缀的同时,也在不断的更新最大值。
我们查询当前 二进制字符串与已经插入的 二进制字符串中的哪一个异或和最大?
找到最大的那个,读取这个前缀和是到谁结束的,来判断是否要更新
/*Keep on going Never give up*/ //#pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> //#define int long long #define endl '\n' #define Accepted 0 #define AK main() #define I_can signed using namespace std; const int maxn =1e7+10; const int MaxN = 0x3f3f3f3f; const int MinN = 0xc0c0c00c; typedef long long ll; const int inf=0x3f3f3f3f; const ll mod=1e9+7; using namespace std; int n,total; int trie[maxn][2],num[maxn]; void ins(int val,int x){ int node=0; for(int i=21;i>=0;i--){ int t=(val>>i)&1; if(!trie[node][t]){ trie[node][t]=++total; } node=trie[node][t]; } num[node]=x; } pair<int,int> quer(int val){ int node=0,res=0; for(int i=21;i>=0;i--){ int t=(val>>i)&1; if(trie[node][t^1]){ res|=1<<i; node=trie[node][t^1]; } else node=trie[node][t]; } return make_pair(res,num[node]); } signed main() { ios::sync_with_stdio(false); int n; cin>>n; int ans=-1,l,r,sum=0; ins(sum,0); for(int i=1;i<=n;i++){ int x; cin>>x; sum^=x; auto res=quer(sum); ins(sum,i); if(res.first>ans){ ans=res.first; l=res.second; r=i; } } cout<<ans<<" "<<l+1<<" "<<r<<endl; return 0; }
题解 文章被收录于专栏
主要写一些题目的题解