样例都不过 蒟蒻求助
查看原帖
样例都不过 蒟蒻求助
234469
activeO楼主2021/7/18 08:42
#include <bits/stdc++.h>

#define int long long

using namespace std;

const int maxn=1e5+10;
struct edge{
    int v,nxt;
}e[2*maxn];
struct Node{
    int sum,lazy;
}tree[2*maxn];
int n,m,r,P;
int a[maxn],cnt,p[maxn];
int f[maxn],d[maxn],sz[maxn];
int son[maxn],rk[maxn];
int top[maxn],id[maxn];

void init(){
	memset(p,-1,sizeof(p));
	cnt=0;
}
void add(int u,int v){
	e[++cnt].v=v;
	e[cnt].nxt=p[u];
	p[u]=cnt;
}

int mod(int x,int y){
	return (x+y)%P;
}

void dfs1(int u,int fa,int h){
	f[u]=fa;
	d[u]=h;
	sz[u]=1;
	for(int i=p[u];i!=-1;i=e[i].nxt){
		int v=e[i].v;
		if(v==fa) continue;
		dfs1(v,u,h+1);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u]=v;
	}
}
void dfs2(int u,int t){
	top[u]=t;
	id[u]=++cnt;
	rk[cnt]=u;
	if(!son[u]) return;
	dfs2(son[u],t);
	for(int i=p[u];i!=-1;i=e[i].nxt){
		int v=e[i].v;
		if(v!=son[u]&&v!=f[u]) dfs2(v,v);
	}
}

void pushup(int x,int l,int r){
	tree[x].sum=((tree[x*2].sum+tree[x*2+1].sum)%P+tree[x].lazy*(r-l+1)%P)%P;
}
void pushdown(int o,int l,int r){
	int mid=(l+r)>>1;
	tree[o*2].sum=mod(tree[o*2].sum,tree[o].lazy*(mid-l+1)%P);
	tree[o*2].lazy=mod(tree[o*2].lazy,tree[o].lazy);
	tree[o*2+1].sum=mod(tree[o*2+1].sum,tree[o].lazy*(r-mid)%P);
	tree[o*2+1].lazy=mod(tree[o*2+1].lazy,tree[o].lazy);
	tree[o].lazy=0;
	
}
void build(int now,int l,int r){
	tree[now].lazy=0;
	if(l==r){
		tree[now].sum=1;
		return;
	}
	int mid=(l+r)>>1;
	build(now*2,l,mid);
	build(now*2+1,mid+1,r);
	pushup(now,l,r);
}
void update(int now,int l,int r,int ql,int qr,int c){
	if(ql<=l&&r<=qr){
		tree[now].sum=mod(tree[now].sum,c*(r-l+1));
		tree[now].lazy=mod(tree[now].lazy,c);
		return;
	}
	if(tree[now].lazy) pushdown(now,l,r);
	int mid=(l+r)>>1;
	if(ql<=mid) update(now*2,l,mid,ql,qr,c);
	if(qr>mid) update(now*2+1,mid+1,r,ql,qr,c);
	pushup(now,l,r);
}
int query(int now,int l,int r,int ql,int qr){
	if(ql<=l&&qr>=r) return tree[now].sum;
	if(tree[now].lazy) pushdown(now,l,r);
	int val=tree[now].lazy*(min(qr,r)-max(ql,l))%P;
	int mid=(l+r)>>1;
	if(ql<=mid) val=(val+query(now*2,l,mid,ql,qr))%P;
	if(mid<qr) val=(val+query(now*2+1,mid+1,r,ql,qr))%P;
	return val;
}
int getsum(int x,int y){
	int ans=0;
	int fx=top[x],fy=top[y];
	while(fx!=fy){
		if(d[fx]>=d[fy]){
			ans=mod(ans,query(1,1,n,id[fx],id[x]));
			x=f[fx];
			fx=top[x];
		}else{
			ans=mod(ans,query(1,1,n,id[fy],id[y]));
			y=f[fy];
			fy=top[y];
		}
	}
	if(id[x]<=id[y]) ans=mod(ans,query(1,1,n,x,y));
	else ans=mod(ans,query(1,1,n,y,x));
	return ans;
}
void change(int x,int y,int c){
	int fx=top[x],fy=top[y];
	while(fx!=fy){
		if(d[fx]>=d[fy]){
			update(1,1,n,id[fx],id[x],c);
			x=f[fx];
			fx=top[x];
		}else{
			update(1,1,n,id[fy],id[y],c);
			y=f[fy];
			fy=top[y];
		}
	}
	if(id[x]<=id[y]) update(1,1,n,id[x],id[y],c);
	else update(1,1,n,id[y],id[x],c);
}

signed main(){
	
	scanf("%lld %lld %lld %lld",&n,&m,&r,&P);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	
	init();
	
	for(int i=1;i<n;i++){
		int x,y;
		scanf("%lld %lld",&x,&y);
		add(x,y);
		add(y,x);
	}
	
	cnt=0;
	dfs1(r,0,1);
	cnt=0;
	dfs2(r,r);
	build(1,1,n);
	
	for(int i=1;i<=m;i++){
		int op,x,y,z;
		scanf("%lld",&op);
		if(op==1){
			scanf("%lld %lld %lld",&x,&y,&z);
			change(x,y,z);
		}else if(op==2){
			scanf("%lld %lld",&x,&y);
			printf("%lld\n",getsum(x,y));
		}else if(op==3){
			scanf("%lld %lld",&x,&z);
			update(1,1,n,id[x],id[x]+sz[x]-1,z);
		}else{
			scanf("%lld",&x);
			printf("%lld\n",query(1,1,n,id[x],id[x]+sz[x]-1));
		}
	}
	
	return 0;
}
2021/7/18 08:42
加载中...