强行把序列问题放树上,好无聊啊~
code:
#include <bits/stdc++.h> #define N 200005 #define setIO(s) freopen(s".in","r",stdin) using namespace std; int tot,edges,tim; int cnt[N*33],ch[N*33][2],tree[N],seq[N],val[N],ba[N]; int fa[N],son[N],size[N],top[N],dep[N],hd[N],to[N<<1],nex[N<<1],dfn[N],ed[N]; inline void add(int u,int v) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; } void insert(int pre,int &x,int v) { int now=x=++tot; for(int i=30;i>=0;--i) { int o=((v>>i)&1); ch[now][o^1]=ch[pre][o^1]; ch[now][o]=++tot; pre=ch[pre][o]; now=tot; cnt[now]=cnt[pre]+1; } } void dfs1(int u,int ff) { fa[u]=ff,dep[u]=dep[ff]+1,size[u]=1,dfn[u]=++tim,ba[tim]=u; for(int i=hd[u];i;i=nex[i]) { int v=to[i]; if(v==ff) continue; insert(tree[u],tree[v],val[v]); dfs1(v,u); size[u]+=size[v]; if(size[v]>size[son[u]]) son[u]=v; } ed[u]=tim; } void dfs2(int u,int tp) { top[u]=tp; if(son[u]) dfs2(son[u],tp); for(int i=hd[u];i;i=nex[i]) if(to[i]!=fa[u]&&to[i]!=son[u]) dfs2(to[i],to[i]); } inline int LCA(int x,int y) { while(top[x]!=top[y]) dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]]; return dep[x]<dep[y]?x:y; } int query1(int x,int y,int z) { int re=0; for(int i=30;i>=0;--i) { int o=((z>>i)&1); if(cnt[ch[y][o^1]]>cnt[ch[x][o^1]]) { re+=(1<<i); y=ch[y][o^1]; x=ch[x][o^1]; } else { y=ch[y][o]; x=ch[x][o]; } } return re; } int query2(int x,int y,int lca,int ff,int z) { int re=0; for(int i=30;i>=0;--i) { int o=((z>>i)&1); if(cnt[ch[x][o^1]]+cnt[ch[y][o^1]]-cnt[ch[lca][o^1]]-cnt[ch[ff][o^1]]) { re+=(1<<i); x=ch[x][o^1]; y=ch[y][o^1]; lca=ch[lca][o^1]; ff=ch[ff][o^1]; } else { x=ch[x][o]; y=ch[y][o]; lca=ch[lca][o]; ff=ch[ff][o]; } } return re; } int main() { // setIO("input"); int i,j,n,m; scanf("%d%d",&n,&m); for(i=1;i<=n;++i) scanf("%d",&val[i]); for(i=1;i<n;++i) { int x,y; scanf("%d%d",&x,&y), add(x,y), add(y,x); } insert(tree[0],tree[1],val[1]); dfs1(1,0); dfs2(1,1); for(i=1;i<=tim;++i) insert(seq[i-1],seq[i],val[ba[i]]); while(m--) { int op,x,y,z; scanf("%d",&op); if(op==1) { scanf("%d%d",&x,&y); printf("%d ",query1(seq[dfn[x]-1],seq[ed[x]],y)); } else { scanf("%d%d%d",&x,&y,&z); int t=LCA(x,y); printf("%d ",query2(tree[x],tree[y],tree[t],tree[fa[t]],z)); } } return 0; }