[TJOI2018]异或【可持久化Trie+树剖】
[TJOI2018]异或
把树剖套的线段树换成可持久化\(Trie\)树就结束了
int val[Maxm], ch[Maxm][2], T_cnt;
void ins(int i, int o, int p, int x, int now){
if(now < 0) {val[o]=i; return;}
int k=x>>now&1; if(ch[p][k^1]) ch[o][k^1]=ch[p][k^1]; ch[o][k]=++T_cnt;
ins(i, ch[o][k], ch[p][k], x, now-1); val[o]=max(val[ch[o][0]], val[ch[o][1]]);
}
int fa[Maxn], top[Maxn], dfn[Maxn], rnk[Maxn], cnt, sz[Maxn], hson[Maxn], dep[Maxn];
void dfs1(int u){ sz[u]=1;
for(int i=head[u], v; i; i=nxt[i])if((v=to[i]) !=fa[u]){
fa[v]=u, dep[v]=dep[u]+1; dfs1(v);
sz[u]+=sz[v]; if(sz[v] > sz[hson[u]]) hson[u]=v;
}
}
void dfs2(int u, int anc){
top[u]=anc; dfn[u]=++cnt; rnk[cnt]=u; if(hson[u]) dfs2(hson[u], anc); else return ;
for(int i=head[u], v; i; i=nxt[i]) if((v=to[i]) != fa[u] && v != hson[u]) dfs2(v, v);
}
int query(int L, int o, int x, int now){
if(now < 0) return v[rnk[val[o]]]^x; int k=x>>now&1;
if(val[ch[o][k^1]] >= L) return query(L, ch[o][k^1], x, now-1);
return query(L, ch[o][k], x, now-1);
}
void cal(int u, int v, int z){
int tu=top[u], tv=top[v], ans=0;
while(tu != tv){
if(dep[tu] < dep[tv]) swap(u, v), swap(tu, tv);
ans=max(ans, query(dfn[tu], rt[dfn[u]], z, 30));
u=fa[tu], tu=top[u];
}
if(dep[u] < dep[v]) swap(u, v); ans=max(ans, query(dfn[v], rt[dfn[u]], z, 30));
printf("%d\n", ans);
}
void solve(){
n=read(), q=read();
for(int i=1; i <= n; i++) v[i]=read();
for(int i=1, u, v; i < n; i++) u=read(), v=read(), add(u, v), add(v, u);
dfs1(1); dfs2(1, 1);
for(int i=1; i <= n; i++) rt[i]=++T_cnt, ins(i, rt[i], rt[i-1], v[rnk[i]], 30);
while(q--){
int cmd=read(), x=read(), y=read(), z;
if(cmd == 1) printf("%d\n", query(dfn[x], rt[dfn[x]+sz[x]-1], y, 30));
else z=read(), cal(x, y, z);
}
}
咸鱼翻身失败