El significado de los problemas
Solicitar con un solo punto modificado entre cualesquiera dos puntos de la longitud de la trayectoria sub-árbol y XOR.
Todos longitud de camino igual y la ruta de XOR.
solución del problema
Simular sencilla qué se puede encontrar.
Un número impar, la respuesta es incluso puntos y XOR.
Con aún más baja, es normal y XOR.
XOR y puntos incluso también son fáciles de manejar.
Apunta a la profundidad de la paridad árbol de Fenwick.
Pero esto es para la cadena, no puede ser directamente
secuencia, lo que se necesita dividida.
Pero yo no, así que para aprender un poco.
medios sencillos:
un nodo secundario de los más grandes sub-árbol como hijo pesada.
Cada prioridad hijo salía pesado, puede hacer
secuencia de la cadena pesada son continuas.
Con esta característica, cuando tratamos a cada cabeza de la cadena de salto, y finalmente continuar el procesamiento de preguntar.
Este que: la complejidad de la cadena de árbol es dividida
pero tengo dos preguntas:
¿Por qué es la complejidad de la garantía, y por qué saltar el primer salto, cuando la primera gran cadena o profundidad
secuencia grande.
Pero ahora no es el punto, traté de conseguir la paloma (obligado a aprender la sección de árbol, recientemente, obviamente, estar en la teoría de grafos)
actualización de un solo punto, tres árboles segmento puede ser.
#include<bits/stdc++.h>
#define FOR(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 2e5+100;
vector<int>G[maxn];
int sz[maxn],son[maxn],dep[maxn];
int dfn[maxn],top[maxn],fa[maxn];
int A[maxn],cnt,n,m;
//剖分
void dfs1(int u,int pre){
dep[u]=dep[pre]+1;
sz[u]=1,fa[u]=pre;
int s=0;
for(auto v:G[u]){
if(v==pre)continue;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[v]>s)son[u]=v,s=sz[v];
}
}
void dfs2(int u,int tr_top){
dfn[u]=++cnt;
top[u]=tr_top;
if(son[u])dfs2(son[u],tr_top);
for(auto v:G[u]){
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
//树状数组
int C[maxn][3];
int lowbit(int x){return (x&(-x));}
void change(int x,int d,int id){for(int i=x;i<=n;i+=lowbit(i))C[i][id]^=d;}
int query(int x,int id){if(x==0)return 0;int ret=0;for(int i=x;i;i-=lowbit(i))ret^=C[i][id];return ret;}
//树链剖分更新
void update(int x,int c){
int val=A[x]^c;
change(dfn[x],val,dep[x]%2);
change(dfn[x],val,2);
if(c)A[x]=c;
}
int query(int l,int r,int id){
int ans=0,now;
if(dep[l]%2!=dep[r]%2)now=2;
else now=(dep[l]%2)^1;
//cout<<id<<"?"<<endl;
while(top[l]!=top[r]){
if(dep[l]<dep[r])swap(l,r);
ans^=query(dfn[l],now)^query(dfn[top[l]]-1,now);
// cout<<dfn[l]<<" "<<dfn[top[l]]-1<<endl;
l=fa[top[l]];
}
// cout<<l<<" "<<r<<" "<<dep[l]%2<<" "<<dep[r]%2<<endl;
if(dfn[l]<=dfn[r])ans^=query(dfn[r],now)^query(dfn[l]-1,now);
else ans^=query(dfn[l],now)^query(dfn[r]-1,now);
//cout<<dfn[l]<<" "<<dfn[r]<<endl;
return ans;
}
int main(){
cin>>n>>m;
FOR(i,1,n)scanf("%d",&A[i]);
FOR(i,1,n-1){
int u,v;scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs1(1,0);
dfs2(1,1);
FOR(i,1,n){
// cout<<i<<" "<<fa[i]<<" "<<sz[i]<<" "<<son[i]<<" "<<dep[i]<<" "<<dfn[i]<<" "<<top[i]<<endl;
}
FOR(i,1,n)update(i,0);
FOR(i,1,m){
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op==1)update(l,r);
else printf("%d\n",query(l,r,i));
}
//cout<<dfn[2]<<endl;
// cout<<query(dfn[2],2)-query(dfn[2]-1,2)<<endl;
}