習題:Deduction Queries(冰茶姬)
阿新 • • 發佈:2020-08-24
題目
思路
考慮到異或的特殊性
將區間轉換成兩個字首異或和的異或即可
程式碼
#include<iostream> #include<cstdio> #include<map> using namespace std; namespace ufs { int fa[400005]; int w[400005]; void makeset(int n) { for(int i=1;i<=n;i++) fa[i]=i; } int findset(int x) { if(fa[x]==x) return x; int t=findset(fa[x]); w[x]^=w[fa[x]]; return fa[x]=t; } void merge(int u,int v,int ty) { swap(u,v); int a=findset(u); int b=findset(v); fa[a]=b; w[a]=w[u]^ty^w[v]; w[b]=0; } } using namespace ufs; int n,cnt; int lans; int opt,l,r,x; map<int,int> hashh; int main() { ios::sync_with_stdio(false); cin>>n; makeset(2*n); for(int i=1;i<=n;i++) { cin>>opt>>l>>r; l^=lans; r^=lans; if(l>r) swap(l,r); l--; if(hashh.count(l)==0) hashh[l]=++cnt; if(hashh.count(r)==0) hashh[r]=++cnt; l=hashh[l]; r=hashh[r]; if(opt==1) { cin>>x; x^=lans; if(findset(l)!=findset(r)) merge(l,r,x); } else { if(findset(l)!=findset(r)) { lans=1; cout<<"-1\n"; } else { lans=w[l]^w[r]; cout<<lans<<'\n'; } } } return 0; }