【可持久化Trie】bzoj 3261 hdu 6191
https://www.cnblogs.com/zcysky/p/6910661.html 江山自有人才出,写的很漂亮,代码一看就懂
bzoj 3261有个坑,就是要把第零个数字也加到trie里,否则可能漏算or算错
bzoj 3261代码
插入的是前缀和,查询的是x^sum[n],贪心得到结果就相当于 x^sum[n]^sum[p-1]=a[p]^a[p+1]...^a[n]^x
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=600060; 4 int n,m,a[N],b[N]; 5 int cnt,bin[32],c[N*25][2],sum[N*25],rt[N]; 6 struct Trie 7 { 8 int ins(int x,int val) 9 { 10 int y,tmp;y=tmp=++cnt; 11 for(int i=24;i>=0;i--) 12 { 13 c[y][0]=c[x][0];c[y][1]=c[x][1]; 14 sum[y]=sum[x]+1; 15 int t=val&bin[i];t=t>>i; 16 x=c[x][t];c[y][t]=++cnt;y=c[y][t]; 17 } 18 sum[y]=sum[x]+1; 19 return tmp; 20 } 21 int query(int l,int r,int val) 22 { 23 int re=0; 24 for(int i=24;i>=0;i--) 25 { 26 int t=val&bin[i];t>>=i; 27 if(sum[c[r][t^1]]-sum[c[l][t^1]]) 28 { 29 re+=bin[i]; 30 r=c[r][t^1];l=c[l][t^1]; 31 } 32 else r=c[r][t],l=c[l][t]; 33 } 34 return re; 35 } 36 }T; 37 void clr() 38 { 39 cnt=0; 40 bin[0]=1; 41 for(int i=1;i<=30;i++)bin[i]=bin[i-1]<<1; 42 c[0][0]=c[0][1]=0; 43 rt[0]=sum[0]=b[0]=0; 44 } 45 int main() 46 { 47 while(~scanf("%d%d",&n,&m)) 48 { 49 clr(); 50 n++;//就是这里 51 for(int i=1;i<=n;i++) 52 { 53 if(i!=1) 54 scanf("%d",a+i); 55 else a[1]=0; 56 b[i]=b[i-1]^a[i]; 57 rt[i]=T.ins(rt[i-1],b[i]); 58 } 59 char s[5]; 60 for(int i=1;i<=m;i++) 61 { 62 scanf("%s",s); 63 if(s[0]=='A') 64 { 65 n++;scanf("%d",a+n); 66 b[n]=b[n-1]^a[n]; 67 rt[n]=T.ins(rt[n-1],b[n]); 68 } 69 else 70 { 71 int l,r,x; 72 scanf("%d%d%d",&l,&r,&x); 73 printf("%d\n",T.query(rt[l-1],rt[r],x^b[n])); 74 } 75 } 76 } 77 return 0; 78 }
hdu 6191
求区间里a[p]异或x最大
#include<bits/stdc++.h> using namespace std; const int N=200020; int n,m; int g[N],v[N],L[N],R[N],tot,dfn,a[N]; struct point { int to,next; }e[500050]; void add(int x,int y) { e[++tot].to=y; e[tot].next=g[x]; g[x]=tot; } void dfs(int x) { L[x]=++dfn; a[dfn]=v[x]; for(int tmp=g[x];tmp;tmp=e[tmp].next) { dfs(e[tmp].to); } R[x]=dfn; } int c[N*31][2],sum[N*31],rt[N],cnt,bin[31]; struct Trie { int ins(int x,int val) { int tmp,y;tmp=y=++cnt; for(int i=30;i>=0;i--) { c[y][0]=c[x][0];c[y][1]=c[x][1]; sum[y]=sum[x]+1; int t=val&bin[i];t>>=i; x=c[x][t];c[y][t]=++cnt;y=c[y][t]; } sum[y]=sum[x]+1; return tmp; } int query(int l,int r,int val) { int re=0; for(int i=30;i>=0;i--) { int t=val&bin[i];t>>=i; if(sum[c[r][t^1]]-sum[c[l][t^1]]) { re+=bin[i]; r=c[r][t^1]; l=c[l][t^1]; } else r=c[r][t],l=c[l][t]; } return re; } }T; void clr() { c[0][0]=c[0][1]=0; for(int i=0;i<=n;i++) rt[i]=g[i]=0; cnt=dfn=tot=0; bin[0]=1; for(int i=1;i<31;i++)bin[i]=bin[i-1]<<1; } int main() { while(~scanf("%d%d",&n,&m)) { clr(); for(int i=1;i<=n;i++) scanf("%d",&v[i]); for(int i=1;i<n;i++) { int x; scanf("%d",&x); add(x,i+1); } dfs(1); for(int i=1;i<=n;i++) { rt[i]=T.ins(rt[i-1],a[i]); } for(int i=1;i<=m;i++) { int u,x; scanf("%d%d",&u,&x); printf("%d\n",T.query(rt[L[u]-1],rt[R[u]],x)); } } return 0; }
(人菜就得多学习