[BZOJ5338][TJOI2018]xor(可持久化Trie)

可持久化Trie模板题。

建两种可持久化Trie,每个点两棵,一棵对DFS求前缀和,一棵对祖先求前缀和。

或者树剖,不好写多少还多个log。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
 4 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
 5 using namespace std;
 6 
 7 const int N=100010;
 8 int n,u,v,Q,x,y,z,op,nd,tim,cnt,t,a[N],rt1[N],rt2[N],fa[N][19];
 9 int h[N],to[N<<1],nxt[N<<1],L[N],R[N],dep[N],ch[N*64][2],d[N*64];
10 
11 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
12 
13 void ins(int &x,int y,int k){
14     int tmp=++nd; x=tmp;
15     for (int i=30; ~i; i--){
16         ch[x][0]=ch[y][0]; ch[x][1]=ch[y][1]; d[x]=d[y]+1;
17         int t=(k>>i)&1; ch[x][t]=++nd; x=ch[x][t]; y=ch[y][t];
18     }
19     d[x]=d[y]+1; x=tmp;
20 }
21 
22 int cal1(int x,int y,int k){
23     int res=0;
24     for (int i=30; ~i; i--){
25         int t=((k>>i)&1)^1;
26         if (d[ch[y][t]]-d[ch[x][t]]) res^=1<<i,x=ch[x][t],y=ch[y][t];
27             else x=ch[x][t^1],y=ch[y][t^1];
28     }
29     return res;
30 }
31 
32 int cal2(int s1,int s2,int s3,int s4,int k){
33     int res=0;
34     for (int i=30; ~i; i--){
35         int t=((k>>i)&1)^1;
36         if (d[ch[s1][t]]+d[ch[s2][t]]-d[ch[s3][t]]-d[ch[s4][t]])
37             res^=1<<i,s1=ch[s1][t],s2=ch[s2][t],s3=ch[s3][t],s4=ch[s4][t];
38         else s1=ch[s1][t^1],s2=ch[s2][t^1],s3=ch[s3][t^1],s4=ch[s4][t^1];
39     }
40     return res;
41 }
42 
43 int Lca(int u,int v){
44     if (dep[u]<dep[v]) swap(u,v);
45     int t=dep[u]-dep[v];
46     for (int i=17; ~i; i--) if (t&(1<<i)) u=fa[u][i];
47     if (u==v) return u;
48     for (int i=17; ~i; i--) if (fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
49     return fa[u][0];
50 }
51 
52 void dfs(int x){
53     rep(i,1,17) fa[x][i]=fa[fa[x][i-1]][i-1];
54     L[x]=++tim; ins(rt1[tim],rt1[tim-1],a[x]);
55     For(i,x) if ((k=to[i])!=fa[x][0])
56         fa[k][0]=x,ins(rt2[k],rt2[x],a[k]),dep[k]=dep[x]+1,dfs(k);
57     R[x]=tim;
58 }
59 
60 int main(){
61     freopen("bzoj5338.in","r",stdin);
62     freopen("bzoj5338.out","w",stdout);
63     scanf("%d%d",&n,&Q);
64     rep(i,1,n) scanf("%d",&a[i]);
65     rep(i,2,n) scanf("%d%d",&u,&v),add(u,v),add(v,u);
66     dfs(1);
67     while (Q--){
68         scanf("%d%d%d",&op,&x,&y);
69         if (op==1) printf("%d\n",cal1(rt1[L[x]-1],rt1[R[x]],y));
70         else scanf("%d",&z),t=Lca(x,y),printf("%d\n",cal2(rt2[x],rt2[y],rt2[t],rt2[fa[t][0]],z));
71     }
72     return 0;
73 }

 

posted @ 2018-12-10 19:21  HocRiser  阅读(235)  评论(0编辑  收藏  举报