萌新求助树剖
查看原帖
萌新求助树剖
233972
秋水1024楼主2021/7/11 10:25

打了四个半小时,实在调不出了,样例都过不去,求大佬查错QAQ

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#define ll long long
using namespace std;
const int N=100086;
int m,n,r,u0,v0;
int fa[N],dep[N],size[N],son[N],top[N],seg[N],rev[N],tot=0;
int f[4*N],laz[4*N],c[4*N],a[N],p;
vector<int>e[N];
void dfs1(int u,int f){
	int v;
	size[u]=1;
	fa[u]=f;
	dep[u]=dep[f]+1;
	for(int i=0;i<e[u].size();i++){
		v=e[u][i];
		if(v==f)continue;
		dfs1(v,u);
		size[u]+=size[v];
		if(size[v]>size[son[u]])son[u]=v;
	}
}
void dfs2(int u,int tp){
	int v;
	seg[u]=++tot;
	rev[tot]=u;
	top[u]=tp;
	if(son[u]){
		v=son[u];
		dfs2(v,tp);
	}
	for(int i=0;i<e[u].size();i++){
		v=e[u][i];
		if(!top[v])dfs2(v,v);
	}
}
void build(int k,int l,int r){
	if(l==r){f[k]=a[rev[l]];return;}
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1+1,mid+1,r);
	f[k]=(f[k<<1]+f[k<<1+1])%p;
}
void add(int k,int l,int r,int v){
	laz[k]=(laz[k]+v)%p;
	f[k]=(f[k]+((r-l+1)*v)%p)%p;return;
}
void push(int k,int l,int r){
	if(laz[k]==0)return;
	int mid=(l+r)>>1;
	add(k<<1,l,mid,laz[k]);
	add(k<<1+1,mid+1,r,laz[k]);
	laz[k]=0;return;
}
void modadd(int k,int l,int r,int x,int y,int v){
	if(x>r||y<l)return;
	if(x<=l&&y>=r)return add(k,l,r,v);
	int mid=(l+r)/2;
	push(k,l,r);
	if(x<=mid)modadd(k*2,l,mid,x,y,v);
	if(mid<y)modadd(k*2+1,mid+1,r,x,y,v);
	f[k]=f[k*2]+f[k*2+1];
}
int modsum(int k,int l,int r,int x,int y){
	if(x>r||y<l)return 0;
	if(x<=l&&y>=r)return f[k];
	int mid=(l+r)>>1,sum=0;
	push(k,l,r);
	if(x<=mid)sum=(sum+modsum(k<<1,l,mid,x,y))%p;
	if(y>mid)sum=(sum+modsum(k<<1+1,mid+1,r,x,y))%p;
	return sum;
}
void linadd(int x,int y,int v){
	while(top[x]!=top[y]){
		if(dep[x]<dep[y])swap(x,y);
		modadd(1,1,tot,seg[x],seg[top[x]],v);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	modadd(1,1,tot,seg[x],seg[y],v);
}
void sonadd(int k,int v){
	return modadd(1,1,tot,seg[k],seg[k]+size[k]-1,v);
}
int linsum(int x,int y){
	int sum=0;
	while(top[x]!=top[y]){
		if(dep[x]<dep[y])swap(x,y);
		sum=(sum+modsum(1,1,tot,seg[x],seg[top[x]]))%p;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y])swap(x,y);
	sum=(sum+modsum(1,1,tot,seg[x],seg[y]))%p;
	return sum;
}
int sonsum(int k){
	return modsum(1,1,tot,seg[k],seg[k]+size[k]-1);
}
/*int out(){
	for(int i=1;i<=4*n;i++)cout<<f[i]<<" ";
	cout<<endl;
}*/
int main()
{
	cin>>n>>m>>r>>p;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<n;i++){
		cin>>u0>>v0;
		e[u0].push_back(v0);
		e[v0].push_back(u0);
	}
	int nn,w0;
	dfs1(r,0);
	//top[r]=r;tot=1;seg[1]=r;rev[r]=1;
	dfs2(r,r);
	build(1,1,tot);
	/*for(int i=1;i<=n;i++){
		cout<<rev[i]<<endl;
	}out();*/
	for(int i=1;i<=m;i++){
		cin>>nn;
		if(nn==1){
			cin>>u0>>v0>>w0;
			linadd(u0,v0,w0%p); 
		}
		if(nn==3){
			cin>>u0>>w0;
			sonadd(u0,w0%p);
		}
		if(nn==2){
			cin>>u0>>v0;
			cout<<linsum(u0,v0)<<endl;
		}
		if(nn==4){
			cin>>u0;
			cout<<sonsum(u0)<<endl;
		}
		//out();
	}
	return 0;
} 
2021/7/11 10:25
加载中...