一本通1762:与非
链接
对于不满足结合律的运算,要处理出两个方向的结果,查询时也要注意方向。
(太菜了。。。被卡常惹。。。
#include<bits/stdc++.h>
#define re register
#define IL inline
#define LL unsigned int
using namespace std;
const int N=1e5+3;
struct hh{
int to,nxt;
}e[N<<1];
int n,m,k,K,num,fir[N],dfn[N],rev[N],top[N],siz[N],son[N],dep[N],fa[N];
LL w[N],Ans,ans[32];
IL LL in(){
char c;
while((c=getchar())<'0'||c>'9');
LL x=c-'0';
while((c=getchar())>='0'&&c<='9')
x=x*10+c-'0';
return x;
}
IL void add(int x,int y){e[++num]=(hh){y,fir[x]},fir[x]=num;}
IL int nand(int x,int y){return !(x&y);}
void dfs1(int u,int f){
fa[u]=f,dep[u]=dep[f]+1,siz[u]=1;
for(re int i=fir[u],v;v=e[i].to;i=e[i].nxt)
if(v^f){
dfs1(v,u),siz[u]+=siz[v];
if(siz[son[u]]<siz[v]) son[u]=v;
}
}
void dfs2(int u,int t){
top[u]=t,rev[dfn[u]=++num]=u;
if(son[u]) dfs2(son[u],t);
for(re int i=fir[u],v;v=e[i].to;i=e[i].nxt)
if(v^fa[u]&&v^son[u]) dfs2(v,v);
}
IL int get_lca(int x,int y){
while(top[x]^top[y]) dep[top[x]]<dep[top[y]]?y=fa[top[y]]:x=fa[top[x]];
return dep[x]<dep[y]?x:y;
}
struct segment{
int L[32][N<<2][2],R[32][N<<2][2];
IL void pushup(int k){
int ls=k<<1,rs=k<<1|1;
for(re int i=0;i<K;++i)
L[i][k][0]=L[i][rs][L[i][ls][0]],
L[i][k][1]=L[i][rs][L[i][ls][1]],
R[i][k][0]=R[i][ls][R[i][rs][0]],
R[i][k][1]=R[i][ls][R[i][rs][1]];
}
IL void gx(int k,LL w){
for(re int i=0;i<K;++i)
L[i][k][0]=R[i][k][0]=nand(0,w>>i&1),
L[i][k][1]=R[i][k][1]=nand(1,w>>i&1);
}
void build(int k,int l,int r){
if(l==r){gx(k,w[rev[l]]);return;}
int mid=l+r>>1;
build(k<<1,l,mid),build(k<<1|1,mid+1,r),pushup(k);
}
void mdy(int k,int l,int r,int u,LL v){
if(l==r){gx(k,v);return;}
int mid=l+r>>1;
if(u<=mid) mdy(k<<1,l,mid,u,v);
else mdy(k<<1|1,mid+1,r,u,v);
pushup(k);
}
void query_R(int k,int l,int r,int ll,int rr){//从下到上
if(l>=ll&&r<=rr){
for(re int i=0;i<K;++i)
ans[i]=R[i][k][ans[i]];
return;
}
int mid=l+r>>1;
if(rr>mid) query_R(k<<1|1,mid+1,r,ll,rr);
if(ll<=mid) query_R(k<<1,l,mid,ll,rr);
}
void query_L(int k,int l,int r,int ll,int rr){//从上到下
if(l>=ll&&r<=rr){
for(int i=0;i<K;++i)
ans[i]=L[i][k][ans[i]];
return;
}
int mid=l+r>>1;
if(ll<=mid) query_L(k<<1,l,mid,ll,rr);
if(rr>mid) query_L(k<<1|1,mid+1,r,ll,rr);
}
}T;
void dfs(int y,int lca){
if(top[y]==top[lca]){
if(y^lca) T.query_L(1,1,n,dfn[lca]+1,dfn[y]);
return;
}
dfs(fa[top[y]],lca);
T.query_L(1,1,n,dfn[top[y]],dfn[y]);
}
int Query(int x,int y){
memset(ans,Ans=0,sizeof(ans));
int lca=get_lca(x,y);
while(top[x]^top[lca])
T.query_R(1,1,n,dfn[top[x]],dfn[x]),x=fa[top[x]];
T.query_R(1,1,n,dfn[lca],dfn[x]);
dfs(y,lca);
for(int i=0;i<K;++i) Ans|=ans[i]<<i;
return Ans;
}
int main()
{
LL x,y,z;char s[10];
n=in(),m=in(),k=K=in();
for(re int i=1;i<=n;++i) w[i]=in();
for(re int i=1;i<n;++i)
x=in(),y=in(),
add(x,y),add(y,x);
num=0,dfs1(1,0),dfs2(1,1);
T.build(1,1,n);
while(m--){
scanf("%s",s+1),x=in(),y=in();
if(s[1]=='Q') printf("%u\n",Query(x,y));
else T.mdy(1,1,n,dfn[x],y);
}
return 0;
}