[TJOI2018]异或

题链

SOL: 我们可以树剖,对dfs序建可持久trie。

#include<bits/stdc++.h>
#define sight(x) ('0'<=x&&x<='9')
#define eho(x) for(int i=head[x];i;i=net[i])
#define v fall[i]
#define N 7000007
#define M 200007
//#define 30 4
int siz[M],son[M],sss[N],s[N][2],tot,tog,tim,ans,n,m,p[N];
int be[N],ed[N],fall[N<<1],net[N<<1],head[N],dep[N],f[N],top[N];
using namespace std;
inline void read(int &x){
    static char c;
    for (c=getchar();!sight(c);c=getchar());
    for (x=0;sight(c);c=getchar())x=x*10+c-48;
}
void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); }
inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
inline void adds(int x,int y){
    fall[++tot]=y; net[tot]=head[x]; head[x]=tot;
    fall[++tot]=x; net[tot]=head[y]; head[y]=tot;
}
void dfs(int x,int fa){
    siz[x]=1;
    eho(x) if (v^fa)  {
      dfs(v,x);
      siz[x]+=siz[v]; 
      if (siz[son[x]]<siz[v]) son[x]=v;
    }
}
int ds[M];
void dfs2(int x,int fa){
    dep[x]=dep[fa]+1; f[x]=fa; 
    be[x]=++tim;  ds[tim]=x;
    if (son[x]) top[son[x]]=top[x],dfs2(son[x],x);
    eho(x) if (v^fa&&v^son[x]) top[v]=v,dfs2(v,x);
    ed[x]=tim;
}
void add(int past,int now,int len,int key){
    sss[now]=sss[past]+1;
    if (len==-1) {return; }
    if ((key>>len)&1) {
        s[now][0]=s[past][0];
        s[now][1]=++tog;
        add(s[past][1],tog,len-1,key);
    } else {
        s[now][1]=s[past][1];
        s[now][0]=++tog;
        add(s[past][0],tog,len-1,key);
    }
}
void query(int past,int now,int len,int key){
    if (len==-1) return;
    assert(sss[now]>0);
    if ((((key>>len)&1)==1)&&(sss[s[now][0]]-sss[s[past][0]]>0)
    ||(((key>>len)&1)==0)&&(sss[s[now][1]]-sss[s[past][1]]==0)) {
        query(s[past][0],s[now][0],len-1,key);
    } else {
        query(s[past][1],s[now][1],len-1,key);    
        ans+=1<<len;
    }
}
int x,y,z,op,ox;
signed main () {
    read(n); read(m);
    for (int i=1;i<=n;i++) read(p[i]);
    for (int i=1;i< n;i++) 
     read(x),read(y),adds(x,y);
    dfs(1,0); top[1]=1;
    dfs2(1,0);
    tog=n;
    for (int i=1;i<=n;i++)
     add(i-1,i,31,p[ds[i]]);
    while (m--) {
        read(op); 
        if (op==1) {
            read(x);read(y);
            ans=0;
            query(be[x]-1,ed[x],31,y);
            writeln(y^ans);
        }
        if (op==2) {
            ox=0; read(x); read(y); read(z);
            while (top[x]^top[y]) {
              ans=0;
               if (dep[top[x]]<dep[top[y]]) swap(x,y); 
               query(be[top[x]]-1,be[x],31,z);
               x=f[top[x]];
              ox=max(ox,ans^z);
            }
            if (be[x]>be[y]) swap(x,y);
            ans=0;
            query(be[x]-1,be[y],31,z);
            ox=max(ox,ans^z);
            writeln(ox);
        }
    } return 0;
}

 

posted @ 2018-05-18 21:31  泪寒之雪  阅读(325)  评论(0编辑  收藏  举报