树剖常规版一直20分 求查错QAQ
查看原帖
树剖常规版一直20分 求查错QAQ
49962
wI9znK4f楼主2018/11/2 20:41
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
inline int Read(){
	int aa=0,w=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') w=-w; c=getchar();}
	while(c>='0'&&c<='9'){aa=(aa<<3)+(aa<<1)+(c^48);c=getchar();}return aa*w;
}const int maxn=200010;
int v[maxn],siz[maxn],dfn[maxn],dep[maxn],rnk[maxn],fa[maxn],head[maxn],top[maxn],son[maxn],S[maxn*5],fl[maxn*5];
struct node{
	int to,nxt;
}a[maxn<<2];int tot,cnt,n,M,R,P;
void DFS1(int now){
	siz[now]=1;	for(int i=head[now];i;i=a[i].nxt){
		int to=a[i].to;	if(to==fa[now]) continue;fa[to]=now;dep[to]=dep[now]+1;DFS1(to); siz[now]+=siz[to];
		if(siz[to]>siz[son[now]])	son[now]=to;
	}return;
}
void DFS2(int now){
	dfn[now]=++cnt; rnk[cnt]=now;
	if(!son[now]) return ;
	top[son[now]]=top[now];	DFS2(son[now]);
	for(int i=head[now];i;i=a[i].nxt){
		int to=a[i].to; if(to==son[now]||to==fa[now]) continue;
		top[to]=to;	DFS2(to);
	}return;
}
void U(int now){
	S[now]=(S[now<<1]+S[now<<1|1])%P;return ;
}
void B(int now,int l,int r){
	if(l==r){S[now]=v[rnk[l]];return ;}
	int mid=(l+r)>>1; B(now<<1,l,mid); B(now<<1|1,mid+1,r);U(now); return ;
}
void PP(int now,int l,int r){
	if(fl[now]==0) return ;
	int mid=(l+r)>>1;
	(fl[now<<1]+=fl[now])%P;	(fl[now<<1|1]+=fl[now])%P;
	S[now<<1]+=fl[now]*(mid-l+1);	S[now<<1]=(S[now<<1])%P;
	S[now<<1|1]+=fl[now]*(r-mid);	S[now<<1|1]=(S[now<<1|1])%P;
	fl[now]=0;
	return ;
}
void TA(int now,int l,int r,int L,int R,int z){
	if(L<=l&&r<=R){(S[now]+=z*(r-l+1))%=P;(fl[now]+=z)%=P;return ;}
	int mid=(l+r)>>1; PP(now,l,r);if(L<=mid) TA(now<<1,l,mid,L,R,z);if(R>mid) TA(now<<1|1,mid+1,r,L,R,z);U(now);return ;
}	
int TQ(int now,int l,int r,int L,int R){
	if(L<=l&&r<=R){return S[now]%P;}	int ans=0;
	int mid=(l+r)>>1; PP(now,l,r);if(L<=mid) (ans+=TQ(now<<1,l,mid,L,R))%=P;if(R>mid) (ans+=TQ(now<<1|1,mid+1,r,L,R))%=P;return ans;
}
void Add(int x,int y){a[++tot].to=y;a[tot].nxt=head[x];head[x]=tot;}
void A1(int x,int y,int z){
	z%=P;
	while(top[x]!=top[y]){
		if(dep[x]<dep[y]) swap(x,y);
		TA(1,1,n,dfn[top[x]],dfn[x],z);	x=fa[top[x]];
	}if(dep[x]>dep[y])	swap(x,y);
	TA(1,1,n,dfn[x],dfn[y],z);
}
int Q1(int x,int y){
	int ans=0; while(top[x]!=top[y]){
		if(dep[x]<dep[y]) swap(x,y);
		(ans+=TQ(1,1,n,dfn[top[x]],dfn[x]))%=P; x=fa[top[x]];
	}if(dep[x]>dep[y])	swap(x,y);
	(ans+=TQ(1,1,n,dfn[x],dfn[y]))%=P;
	return ans;
}
void A2(int x,int z){
	z%=P;	TA(1,1,n,dfn[x],dfn[x]+siz[x]-1,z);
}
int Q2(int x){
	int ans=0; (ans+=TQ(1,1,n,dfn[x],dfn[x]+siz[x]-1))%=P;return ans;
}
signed main(){
//	freopen("in.in","r",stdin);
//	freopen("T1.out","w",stdout);
	n=Read(),M=Read(),R=Read(),P=Read();
	for(int i=1;i<=n;i++)	v[i]=Read();
	for(int i=1;i<n;i++){int x=Read();int y=Read();Add(x,y);Add(y,x);}
	dep[R]=1;	fa[R]=R;	DFS1(R);	top[R]=R;	DFS2(R);	B(1,1,n);
	for(int i=1;i<=M;i++){int ops=Read();
		if(ops==1){int x=Read();int y=Read();int z=Read();A1(x,y,z);}
		if(ops==2){int x=Read();int y=Read();printf("%lld\n",Q1(x,y));}
		if(ops==3){int x=Read();int z=Read();A2(x,z);}
		if(ops==4){int x=Read();printf("%lld\n",Q2(x));}
	}return 0;
}
2018/11/2 20:41
加载中...