zoukankan      html  css  js  c++  java
  • [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
    ",cal1(rt1[L[x]-1],rt1[R[x]],y));
    70         else scanf("%d",&z),t=Lca(x,y),printf("%d
    ",cal2(rt2[x],rt2[y],rt2[t],rt2[fa[t][0]],z));
    71     }
    72     return 0;
    73 }
  • 相关阅读:
    Android 拍照 代码实例
    利用Android手机里的摄像头进行拍照
    看视频时,类加载器没太理解,现在再整理下几个要点
    关于java设计模式与极品飞车游戏的思考
    【Mood-3】心声
    源自梦想 eclipse快捷键整理
    2020重新出发,JAVA语言,JAVA的诞生和发展史
    2020重新出发,序章: 语言的诞生
    2020重新出发,JAVA学前了解,DOS常用命令
    2020重新出发,JAVA学前了解,Windosws常用快捷键
  • 原文地址:https://www.cnblogs.com/HocRiser/p/10098487.html
Copyright © 2011-2022 走看看