一开始开了31个线段树sum维护区间异或和,然后第五个点T了,之后又sum维护区间1的个数,然后第12个点T了,然后又把两个循环合成了一个,然后提前算出来了一个数就A了,感觉时间卡的很离谱。 卡时间垃圾题。基本都是板子。
#include<iostream>
#include<cstdio>
using namespace std;
const int MAX_N=100100;
int head[MAX_N],ver[2*MAX_N],Next[2*MAX_N];
int tot,cnt;
void Add(int x,int y){
ver[++tot]=y;Next[tot]=head[x];head[x]=tot;
}
int size[MAX_N],wson[MAX_N],dfn[MAX_N],deep[MAX_N],pre[MAX_N],top[MAX_N],fa[MAX_N];
struct node{
int l,r,sum,lazy;
}a[32][MAX_N*4];
int b[MAX_N];
void update(int t,int k){
a[t][k].sum=a[t][k<<1].sum+a[t][k<<1|1].sum;
}
void build(int t,int k,int l,int r){
a[t][k].l=l;a[t][k].r=r;a[t][k].lazy=-1;
if(l==r){
a[t][k].sum=(b[pre[l]]>>t)&1;
return;
}
int mid=(l+r)>>1;
build(t,k<<1,l,mid);
build(t,k<<1|1,mid+1,r);
update(t,k);
}
void pushdown(int t,int k){
if(a[t][k].lazy==-1)
return;
a[t][k<<1].lazy=a[t][k<<1|1].lazy=a[t][k].lazy;
if(a[t][k].lazy==1){
a[t][k<<1].sum=a[t][k<<1].r-a[t][k<<1].l+1;
a[t][k<<1|1].sum=a[t][k<<1|1].r-a[t][k<<1|1].l+1;
}
else{
a[t][k<<1].sum=0;
a[t][k<<1|1].sum=0;
}
a[t][k].lazy=-1;
}
void changeS(int t,int k,int l,int r,int y){
if(a[t][k].l>=l&&a[t][k].r<=r){
if(y==0)
a[t][k].sum=0;
else
a[t][k].sum=a[t][k].r-a[t][k].l+1;
a[t][k].lazy=y;
return;
}
pushdown(t,k);
int mid=(a[t][k].l+a[t][k].r)>>1;
if(l<=mid)
changeS(t,k<<1,l,r,y);
if(r>mid)
changeS(t,k<<1|1,l,r,y);
update(t,k);
}
int query(int t,int k,int l,int r){
if(a[t][k].l>=l&&a[t][k].r<=r)
return a[t][k].sum;
pushdown(t,k);
int mid=(a[t][k].l+a[t][k].r)>>1;
int x=0;
if(l<=mid)
x+=query(t,k<<1,l,r);
if(r>mid)
x+=query(t,k<<1|1,l,r);
return x;
}
void dfs1(int x,int fat){
size[x]=1;
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y==fat)
continue;
deep[y]=deep[x]+1;
fa[y]=x;
dfs1(y,x);
size[x]+=size[y];
if(size[wson[x]]<size[y])
wson[x]=y;
}
}
void dfs2(int x,int tp){
dfn[x]=++cnt;
pre[cnt]=x;
top[x]=tp;
if(wson[x])
dfs2(wson[x],tp);
for(int i=head[x];i;i=Next[i]){
int y=ver[i];
if(y!=wson[x]&&y!=fa[x])
dfs2(y,y);
}
}
void modify1(int x,int y,int d){//修改x到y路径上的值
while(top[x]!=top[y]){
if(dfn[top[x]]<dfn[top[y]])
swap(x,y);
for(int i=0;i<31;i++){
if((d>>i)&1)
changeS(i,1,dfn[top[x]],dfn[x],1);
}
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
for(int i=0;i<31;i++){
if((d>>i)&1)
changeS(i,1,dfn[x],dfn[y],1);
}
}
void modify2(int x,int y,int d){//修改x到y路径上的值
while(top[x]!=top[y]){
if(dfn[top[x]]<dfn[top[y]])
swap(x,y);
for(int i=0;i<31;i++){
if(!((d>>i)&1))
changeS(i,1,dfn[top[x]],dfn[x],0);
}
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
for(int i=0;i<31;i++){
if(!((d>>i)&1))
changeS(i,1,dfn[x],dfn[y],0);
}
}
int Qsum(int x,int y){
int ans[35]={0};
int ret=0;
while(top[x]!=top[y]){
if(dfn[top[x]]<dfn[top[y]])
swap(x,y);
for(int i=0;i<31;i++){
ans[i]+=query(i,1,dfn[top[x]],dfn[x]);
}
x=fa[top[x]];
}
if(deep[x]>deep[y])
swap(x,y);
for(int i=0;i<31;i++){
ans[i]+=query(i,1,dfn[x],dfn[y]);
ret+=(ans[i]&1)<<i;
}
return ret;
}
int main(void){
int n,m,i,op,s,t,x,y;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&b[i]);
}
for(i=1;i<n;i++){
scanf("%d%d",&x,&y);
Add(x,y);
Add(y,x);
}
deep[1]=1;
dfs1(1,0);
dfs2(1,1);
for(i=0;i<31;i++)
build(i,1,1,n);
for(i=0;i<m;i++){
scanf("%d%d%d",&op,&s,&t);
if(op==1){
modify1(1,s,t);
}
else if(op==2){
modify2(1,s,t);
}
else if(op==3){
int ans=Qsum(1,s);
//cout<<ans<<"!!\n";
ans^=t;
if(ans)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}