题目链接
首先很显然每一位计算的结果是独立的。
先对树进行树链剖分,每一条重链维护一棵线段树,每个线段树区间维护两个数组 ( t 0 , t 1 ) (t_0,t_1) (t0,t1)分别表示某个数某一位为 0 / 1 0/1 0/1时经过这段区间的运算这一位会变成 0 0 0还是 1 1 1,这两个数组可以用两个 u n s i g n e d l o n g l o n g unsigned\ long\ long unsigned long long压起来,但运算顺序可能是深度从大到小,也可能是从小到大,所以要维护两对 ( t 0 , t 1 ) (t_0,t_1) (t0,t1)。修改都是线段树单点修改,询问的话就先把对应链上的 ( t 0 , t 1 ) (t_0,t_1) (t0,t1)求出来,然后贪心的从高位往低位依次确定答案即可。
时间复杂度 O ( n l o g 2 n ) O(n log ^2\ n) O(nlog2 n)。
#include
#include
#include
#include
#define fo(i,j,l) for(int i=j;i<=l;++i)
#define fd(i,j,l) for(int i=j;i>=l;--i)
using namespace std;
typedef long long ll;
typedef unsigned long long kk;
const ll N=52e4,M=N<<1,K=N*8,mo=1e9+7;
const kk U=((((kk)1<<63)-1)<<1)^1;
int ls[K],rs[K];
kk t[K][2][2];
int n,m,x,y,ko,oo;
int la[N],lb[M],ne[M];
int size[N],hs[N],gf[N],fa[N],dep[N],len[N],pp[N];
int fh[N];
kk bq[N];
kk t0,t1;
int f[N][20];
int yy[N][3];
inline void llb(int a,int b)
{ne[++oo]=la[a]; la[a]=oo; lb[oo]=b;}
inline int read()
{
int o=0; char ch=' ';
for(;ch<'0'||ch>'9';ch=getchar());
for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+(ch^48);
return o;
}
inline kk _read()
{
kk o=0; char ch=' ';
for(;ch<'0'||ch>'9';ch=getchar());
for(;ch>='0'&&ch<='9';ch=getchar())o=o*10+(ch^48);
return o;
}
inline void dg(int o)
{
size[o]=1;
for(int y=la[o];y;y=ne[y])
if(!fa[lb[y]]){
fa[lb[y]]=o;
f[lb[y]][0]=o;
for(int l=0;f[f[lb[y]][l]][l];++l)
f[lb[y]][l+1]=f[f[lb[y]][l]][l];
dep[lb[y]]=dep[o]+1;
dg(lb[y]);
size[o]+=size[lb[y]];
if(size[lb[y]]>size[hs[o]])hs[o]=lb[y];
}
}
inline void dfs(int o)
{
++len[gf[o]];
for(int y=la[o];y;y=ne[y])
if(fa[lb[y]]==o){
if(lb[y]==hs[o])gf[lb[y]]=gf[o];
else gf[lb[y]]=lb[y];
dfs(lb[y]);
}
}
inline void build(int o,int l,int r)
{
if(l==r){
t[o][1][1]=t[o][1][0]=t[o][0][0]=t[o][0][1]=0;
return;
}
int mid=l+r>>1;
ls[o]=++ko;
build(ls[o],l,mid);
rs[o]=++ko;
build(rs[o],mid+1,r);
t[o][0][0]=t[o][1][0]=0;
t[o][0][1]=t[o][1][1]=U;
}
inline void updata(int o)
{
int le=ls[o],ri=rs[o];
t[o][0][0]=((t[le][0][0]^U)&t[ri][0][0])^((t[le][0][0]&t[ri][0][1]));
t[o][0][1]=((t[le][0][1]^U)&t[ri][0][0])^((t[le][0][1]&t[ri][0][1]));
t[o][1][0]=((t[ri][1][0]^U)&t[le][1][0])^((t[ri][1][0]&t[le][1][1]));
t[o][1][1]=((t[ri][1][1]^U)&t[le][1][0])^((t[ri][1][1]&t[le][1][1]));
}
inline void cor(int o,int l,int r,int po,kk a,int b)
{
if(l==r){
if(b==1)t[o][0][0]=0,t[o][0][1]=a;
if(b==2)t[o][0][0]=a,t[o][0][1]=U;
if(b==3)t[o][0][0]=a,t[o][0][1]=U^a;
if(b==1)t[o][1][0]=0,t[o][1][1]=a;
if(b==2)t[o][1][0]=a,t[o][1][1]=U;
if(b==3)t[o][1][0]=a,t[o][1][1]=U^a;
return;
}
int mid=l+r>>1;
if(po<=mid)cor(ls[o],l,mid,po,a,b);
else cor(rs[o],mid+1,r,po,a,b);
updata(o);
}
inline void ask1(int o,int l,int r,int le,int ri)
{
if(l==le&&r==ri){
t0=((t0^U)&t[o][0][0])^(t0&t[o][0][1]);
t1=((t1^U)&t[o][0][0])^(t1&t[o][0][1]);
return;
}
int mid=l+r>>1;
if(ri<=mid)ask1(ls[o],l,mid,le,ri);
else if(le>mid)ask1(rs[o],mid+1,r,le,ri);
else {
ask1(ls[o],l,mid,le,mid);
ask1(rs[o],mid+1,r,mid+1,ri);
}
}
inline void ask2(int o,int l,int r,int le,int ri)
{
if(l==le&&r==ri){
t0=((t0^U)&t[o][1][0])^(t0&t[o][1][1]);
t1=((t1^U)&t[o][1][0])^(t1&t[o][1][1]);
return;
}
int mid=l+r>>1;
if(ri<=mid)ask2(ls[o],l,mid,le,ri);
else if(le>mid)ask2(rs[o],mid+1,r,le,ri);
else {
ask2(rs[o],mid+1,r,mid+1,ri);
ask2(ls[o],l,mid,le,mid);
}
}
inline int lca(int x,int y)
{
if(dep[y]<dep[x])swap(x,y);
for(int l=19;l>=0;--l)if(dep[f[y][l]]>=dep[x])y=f[y][l];
for(int l=19;l>=0;--l)if(f[x][l]!=f[y][l])x=f[x][l],y=f[y][l];
return (x!=y)?(fa[x]):x;
}
inline kk ques(ll sj,int x,int y)
{
int z=lca(x,y);
t0=0,t1=U;
while(dep[gf[x]]>=dep[z]){
ask2(gf[x],1,len[x],1,pp[x]);
x=fa[gf[x]];
}
if(dep[x]>=dep[z])ask2(gf[x],1,len[x],pp[z],pp[x]);
int e=0;
while(dep[gf[y]]>dep[z]){
++e;
yy[e][0]=gf[y];
yy[e][1]=1; yy[e][2]=pp[y];
y=fa[gf[y]];
}
if(dep[y]>dep[z]){
++e;
yy[e][0]=gf[y];
yy[e][1]=pp[z]+1;
yy[e][2]=pp[y];
}
fd(i,e,1)ask1(yy[i][0],1,len[yy[i][0]],yy[i][1],yy[i][2]);
kk sx=0,ans=0;
kk dd=(kk)1<<63;
fo(i,1,64){
kk k1=0,k2=0;
if((sx|dd)<=sj)k1=t1ⅆ
k2=t0ⅆ
if(k2>=k1)ans=ans|k2;
else ans|=k1,sx|=dd;
dd>>=1;
}
return ans;
}
int main()
{
int useless;
scanf("%d%d%d",&n,&m,&useless);
fo(i,1,n)fh[i]=read(),bq[i]=_read();
fo(i,1,n-1)x=read(),y=read(),llb(x,y),llb(y,x);
ko=n;
fa[1]=-1; gf[1]=dep[1]=1;
dg(1); dep[1]=1; dfs(1); fa[1]=0;
fo(i,1,n)if(gf[i]==i)build(i,1,len[i]);
fo(i,1,n)len[i]=len[gf[i]],pp[i]=dep[i]-dep[gf[i]]+1;
fo(i,1,n)cor(gf[i],1,len[i],pp[i],bq[i],fh[i]);
fo(i,1,m){
int op=read();
if(op==2){
x=read();
fh[x]=read();
bq[x]=_read();
cor(gf[x],1,len[x],pp[x],bq[x],fh[x]);
}
if(op==1){
x=read(); y=read();
kk z=_read();
kk ans=ques(z,x,y);
printf("%llu\n",ans);
}
}
}