树剖板子10pts AC on #11 求调
查看原帖
树剖板子10pts AC on #11 求调
655088
TBSF_0207楼主2024/4/4 21:54

悬关

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,r,mod;
struct Edge{int to,next;}e[N<<1];
int head[N<<1],cnt;
void init(){
	for(int i=0;i<2*N;i++){
		e[i].next=-1;
		head[i]=-1;
	}
	cnt=0;
}
void addedge(int u,int v){
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt++;
}
int ls(int x){return x<<1;}
int rs(int x){return x<<1|1;}
int w[N],w_new[N];
int tree[N<<2],tag[N<<2];
void addtag(int p,int pl,int pr,int d){
	tag[p]+=d;
	tree[p]+=d*(pr-pl+1);
	tree[p]%=mod;
}
void push_up(int p){tree[p]=(tree[ls(p)]+tree[rs(p)])%mod;}
void push_down(int p,int pl,int pr){
	if(tag[p]){
		int mid=(pl+pr)>>1;
		addtag(ls(p),pl,mid,tag[p]);
		addtag(rs(p),mid+1,pr,tag[p]);
		tag[p]=0;
	}
}
void build(int p,int pl,int pr){
	tag[p]=0;
	if(pl==pr){
		tree[p]=w_new[p];
		tree[p]%=mod;
		return ;
	}
	int mid=(pl+pr)>>1;
	build(ls(p),pl,mid);
	build(rs(p),mid+1,pr);
	push_up(p); 
}
void upd(int L,int R,int p,int pl,int pr,int d){
	if(L<=pl&&pr<=R){addtag(p,pl,pr,d);return ;}
	push_down(p,pl,pr);
	int mid=(pl+pr)>>1;
	if(L<=mid)upd(L,R,ls(p),pl,mid,d);
	if(R>mid)upd(L,R,rs(p),mid+1,pr,d);
	push_up(p);
}
int query(int L,int R,int p,int pl,int pr){
	if(L<=pl&&pr<=R)return tree[p]%=mod;
	push_down(p,pl,pr);
	int res=0;
	int mid=(pl+pr)>>1;
	if(L<=mid)res+=query(L,R,ls(p),pl,mid);
	if(R>mid)res+=query(L,R,rs(p),mid+1,pr);
	return res;
}
int son[N],id[N],fa[N],dep[N],siz[N],top[N];
void dfs1(int u,int fat){
	dep[u]=dep[fat]+1;
	fa[u]=fat;
	siz[u]=1;
	for(int i=head[u];~i;i=e[i].next){
		int v=e[i].to;
		if(v==fat)continue;
		fa[v]=u;
		dfs1(v,u);
		siz[u]+=siz[v];
		if((!son[u])||siz[son[u]]<siz[v])son[u]=v;
	}
}
int num=0;
void dfs2(int x,int topx){
	id[x]=++num;
	w_new[num]=w[x];
	top[x]=topx;
	if(!son[x])return ;
	dfs2(son[x],topx);
	for(int i=head[x];~i;i=e[i].next){
		int v=e[i].to;
		if(v!=fa[x]&&v!=son[x])dfs2(v,v);
	}
}
void updr(int x,int y,int z){
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		upd(id[top[x]],id[x],1,1,n,z);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	upd(id[x],id[y],1,1,n,z);
}
int quer(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ans+=query(id[top[x]],id[x],1,1,n);
		ans%=mod;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	ans+=query(id[x],id[y],1,1,n);
	return ans%mod;
}
void upd_tre(int x,int k){upd(id[x],id[x]+siz[x]-1,1,1,n,k);}
int query_tree(int x){return query(id[x],id[x]+siz[x]-1,1,1,n)%mod;}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	init();
	cin>>n>>m>>r>>mod;
	for(int i=1;i<=n;i++)cin>>w[i];
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		addedge(u,v);
		addedge(v,u);
	}
	dfs1(r,0);
	dfs2(r,r);
	build(1,1,n);
	while(m--){
		int k,x,y,z;
		cin>>k;
		if(k==1){cin>>x>>y>>z;updr(x,y,z);}
		else if(k==2){cin>>x>>y;cout<<quer(x,y)<<'\n';}
		else if(k==3){cin>>x>>y;upd_tre(x,y);}
		else if(k==4){cin>>x;cout<<query_tree(x)<<'\n';}
	}
	return 0;
}
2024/4/4 21:54
加载中...