萌新刚学OI 树剖板子73pts求助
查看原帖
萌新刚学OI 树剖板子73pts求助
735763
_ChongYun_楼主2024/10/16 07:24

RE on #8,#9,#10

应该不是数组的问题。我已经开到1e7了(

#include<bits/stdc++.h>
using namespace std;
int n,q,rt,mod,a[10000005];
struct SegTree{
	int l,r,sum;
}tree[20000005];
int lazy[20000005];
struct node{
	int to,nxt,val;
}w[20000005];
int h[20000005],cnt=0;
void Link(int x,int y){
	++cnt;
	w[cnt].to=y;
	w[cnt].nxt=h[x];
	h[x]=cnt;
	return ;
}
int f[10000005],siz[10000005],dep[10000005];
int son[10000005],top[10000005];
int id[10000005],rk[10000005],tot=0;
void firdfs(int x,int fa){
	f[x]=fa; siz[x]=1; dep[x]=dep[fa]+1;
	for(int i=h[x];i!=0;i=w[i].nxt){
		int y=w[i].to;
		if(y==fa) continue;
		firdfs(y,x);
		siz[x]+=siz[y];
		if(siz[y]>siz[son[x]]) son[x]=y;
	}
	return ;
}
void secdfs(int x,int tp){
	top[x]=tp; id[x]=++tot; rk[tot]=x;
	if(!son[x]) return ;
	secdfs(son[x],tp);
	for(int i=h[x];i!=0;i=w[i].nxt){
		int y=w[i].to;
		if(y==son[x]) continue;
		if(y==f[x]) continue;
		secdfs(y,y);
	}
	return ;
}
void pushup(int p){
	tree[p].sum=(tree[p<<1].sum+tree[p<<1|1].sum)%mod;
	return ;
}
void pushdown(int p){
	if(lazy[p]){
		tree[p<<1].sum=(tree[p<<1].sum+lazy[p]*(tree[p<<1].r-tree[p<<1].l+1)%mod)%mod;
		tree[p<<1|1].sum=(tree[p<<1|1].sum+lazy[p]*(tree[p<<1|1].r-tree[p<<1|1].l+1)%mod)%mod;
		lazy[p<<1]=(lazy[p<<1]+lazy[p])%mod; lazy[p<<1|1]=(lazy[p<<1|1]+lazy[p])%mod;
		lazy[p]=0;
	}
	return ;
}
void build(int p,int l,int r){
	tree[p].l=l; tree[p].r=r;
	lazy[p]=0; tree[p].sum=a[rk[l]]%mod;
	if(l==r) return ;
	int mid=(l+r)>>1;
	build(p<<1,l,mid);
	build(p<<1|1,mid+1,r);
	pushup(p);
	return ;
}
void update(int p,int l,int r,int val){
	if(l<=tree[p].l&&tree[p].r<=r){
		tree[p].sum=(tree[p].sum+val*(tree[p].r-tree[p].l+1)%mod)%mod;
		lazy[p]=(lazy[p]+val)%mod;
		return ;
	}
	pushdown(p);
	int mid=(tree[p].l+tree[p].r)>>1;
	if(l<=mid) update(p<<1,l,r,val);
	if(r>mid) update(p<<1|1,l,r,val);
	pushup(p);
	return ;
}
int query(int p,int l,int r){
	if(l<=tree[p].l&&tree[p].r<=r) return tree[p].sum;
	pushdown(p);
	int qans=0,mid=(tree[p].l+tree[p].r)>>1;
	if(l<=mid) qans=(qans+query(p<<1,l,r)%mod)%mod;
	if(r>mid) qans=(qans+query(p<<1|1,l,r)%mod)%mod;
	return qans;
}
void update0(int x,int y,int val){
	int tx=top[x],ty=top[y];
	while(tx!=ty){
		if(dep[tx]>=dep[ty]){
			update(rt,id[tx],id[x],val);
			x=f[tx]; tx=top[x];
		}else{
			update(rt,id[ty],id[y],val);
			y=f[ty]; ty=top[y];
		}
	}
	if(id[x]<=id[y]) update(rt,id[x],id[y],val);
	else update(rt,id[y],id[x],val);
	return ;
}
int query0(int x,int y){
	int qans=0;
	int tx=top[x],ty=top[y];
	while(tx!=ty){
		if(dep[tx]>=dep[ty]){
			qans=(qans+query(rt,id[tx],id[x])%mod)%mod;
			x=f[tx]; tx=top[x];
		}else{
			qans=(qans+query(rt,id[ty],id[y])%mod)%mod;
			y=f[ty]; ty=top[y];
		}
	}
	if(id[x]<=id[y]) qans=(qans+query(rt,id[x],id[y])%mod)%mod;
	else qans=(qans+query(rt,id[y],id[x])%mod)%mod;
	return qans;
}
int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*f;
}
signed main(){
	n=read(); q=read(); rt=read(); mod=read();
	for(int i=1;i<=n;i++) a[i]=read(); 
	for(int i=1;i<n;i++){
		int u,v;
		u=read(); v=read();
		Link(u,v);
		Link(v,u);
	}
	firdfs(rt,0); 
	secdfs(rt,rt);
	build(rt,1,n);
	while(q--){
		int op=read();
		if(op==1){
			int x,y,val;
			x=read(); y=read();
			val=read();
			update0(x,y,val);
		}
		if(op==2){
			int x,y;
			x=read(); y=read();
			printf("%lld\n",query0(x,y));
		}
		if(op==3){
			int x,val;
			x=read(); val=read();
			update(rt,id[x],id[x]+siz[x]-1,val);
		}
		if(op==4){
			int x=read();
			printf("%lld\n",query(rt,id[x],id[x]+siz[x]-1));
		}
	}
	return 0;
}
2024/10/16 07:24
加载中...