树剖板子10分求调
查看原帖
树剖板子10分求调
593595
_Aurore_楼主2022/10/14 17:32
#include<bits/stdc++.h>
#define int long long
#define INF 100000000000000
#define MAXN 100001
using namespace std;
inline 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*10+ch-48;ch=getchar();}
	return x*f;
}
int n,m,r,p,cnt;
int val[MAXN];
struct node{
	int x,id,top;
	int dep,dad,maxson,size;
}a[MAXN];
struct tree{
	int sum,tag;
}t[MAXN*4];
vector<int> e[MAXN];
void dfs1(int x,int dad,int d){
	a[x].dep=d;
	a[x].dad=dad;
	int mx=-INF;
	for(int i=0;i<e[x].size();i++)
	    if(e[x][i]!=dad){
	    	int to=e[x][i];
	    	dfs1(to,x,d+1);
	    	a[x].size+=a[to].size;
	    	if(a[to].size>mx){
	    		a[x].maxson=to;
	    		mx=a[to].size;
			}
		}
	++a[x].size;
}
void dfs2(int x,int top){
	a[x].id=++cnt;
	val[cnt]=a[x].x;
	a[x].top=top;
	if(!a[x].maxson)
	    return ;
    dfs2(a[x].maxson,top);
    for(int i=0;i<e[x].size();i++)
        if(e[x][i]!=a[x].dad&&e[x][i]!=a[x].maxson){
        	int to=e[x][i];
        	dfs2(to,to);
		}
}
void build(int i,int l,int r){
	if(l==r){
		t[i].sum=val[l]%p;
		t[i].tag=0;
		return ;
	}
	int mid=(l+r)/2;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);	
	t[i].tag=0;
	t[i].sum=(t[i*2].sum+t[i*2+1].sum)%p; 
}
void pushdown(int i,int l,int r){
	t[i*2].tag+=t[i].tag;
	t[i*2+1].tag+=t[i].tag;
	int mid=(l+r)/2;
	t[i*2].sum=(t[i*2].sum+(mid-l+1)*t[i].tag)%p;
	t[i*2+1].sum=(t[i*2+1].sum+(r-mid)*t[i].tag)%p;
	t[i].tag=0;
}
int query(int i,int l,int r,int L,int R){
    if(L>R)
        swap(L,R);
	if(L<=l&&r<=R)
		return t[i].sum;
	if(l>R||r<L)
	    return 0;
	int mid=(l+r)/2,sum=0;
	if(t[i].tag)
	    pushdown(i,l,r);
	if(mid>=L)
	    sum=(sum+query(i*2,l,mid,L,R))%p;
	if(mid<R)
	    sum=(sum+query(i*2+1,mid+1,r,L,R))%p;
	return sum; 
}
void update(int i,int l,int r,int L,int R,int k){
	if(L>R)
	    swap(L,R);
	if(L<=l&&r<=R){
		t[i].tag+=k;
		t[i].sum=(t[i].sum+(r-l+1)*k)%p;
		return ;
	}
	if(l>R||r<L)
	    return ;
	int mid=(l+r)/2;
	if(t[i].tag)
	    pushdown(i,l,r);
	if(mid>=L)
	    update(i*2,l,mid,L,R,k);
	if(mid<R)
	    update(i*2+1,mid+1,r,L,R,k);
}
int Qroute(int x,int y){
	int ans=0;
	while(a[x].top!=a[y].top){
		if(a[a[x].top].dep<a[a[y].top].dep)
		    swap(x,y);
		ans=(ans+query(1,1,n,a[a[x].top].id,a[x].id))%p;
		x=a[a[x].top].dad;
	} 
	if(a[x].dep<a[y].dep)
	    swap(x,y);
	ans=(ans+query(1,1,n,a[x].id,a[y].id))%p;
	return ans;
}
int Qtree(int root){
	int ans=0;
	ans=(ans+query(1,1,n,a[root].id,a[root].id+a[root].size-1))%p;
	return ans;
}
int UProute(int x,int y,int k){
	k=k%p;
	while(a[x].top!=a[y].top){
		if(a[a[x].top].dep<a[a[y].top].dep)
		    swap(x,y);
		update(1,1,n,a[a[x].top].id,a[x].id,k);
		x=a[a[x].top].dad;
	}
	if(a[x].dep<a[y].dep)
	    swap(x,y);
	update(1,1,n,a[x].id,a[y].id,k);
}
int UPtree(int root,int k){
	k=k%p;
	update(1,1,n,a[root].id,a[root].id+a[root].size-1,k);
}
signed main(){
	n=read(),m=read(),r=read(),p=read(); 
	for(int i=1;i<=n;i++)
	    a[i].x=read();
	for(int i=1;i<n;i++){
		int x=read(),y=read();
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt=read();
		if(opt==1){
			int x=read(),y=read(),z=read();
			UProute(x,y,z);
		}
		else if(opt==2){
			int x=read(),y=read();
			cout<<Qroute(x,y)%p<<endl;
		}
		else if(opt==3){
			int x=read(),k=read();
			UPtree(x,k);
		}
		else{
			int x=read();
			cout<<Qtree(x)%p<<endl;
		}
	}
	return 0;
}
2022/10/14 17:32
加载中...