大佬求调
查看原帖
大佬求调
550970
Aliya_Hyacinth楼主2024/6/28 21:23

不知道错哪里了,调了很久

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=2e5+5;

struct path{
	ll u,v,nxt;
}e[N*2];
int head[N];
int num;
inline void addpath(int x,int y){
	e[++num].u=x;
	e[num].v=y;
	e[num].nxt=head[x];
	head[x]=num;
	return ;
}

int deep[N];
int fa[N];
int son[N];
int tot[N];
int top[N];
int idx[N];

int n,m,r,mod,cnt,a[N],b[N];
int op,xx,yy,k;

inline int dfs1(int now,int f,int dep){
	deep[now]=dep;
	fa[now]=f;
	tot[now]=1;
	int maxson=-1;
	for(int i=head[now];i!=-1;i=e[i].nxt){
		if(e[i].v==f)
			continue;
		tot[now]+=dfs1(e[i].v,now,dep+1);
		if(tot[e[i].v]>maxson)
			maxson=tot[e[i].v],son[now]=e[i].v;
	}
	return tot[now];
}

inline void dfs2(int now,int topf){
	idx[now]=++cnt;
	a[cnt]=b[now];
	top[now]=topf;
	if(!son[now])
		return ;
	dfs2(son[now],topf);
	for(int i=head[now];i!=-1;i=e[i].nxt)
		if(!idx[e[i].v])
			dfs2(e[i].v,e[i].v);
	return ;
}

struct node{
	int l,r;
	int tag;
	int sum;
}tree[N*4];

inline void build(int i,int l,int r){
	tree[i].l=l;
	tree[i].r=r;
	if(l==r){
		tree[i].sum=a[l];
		return ;
	}
	int mid=(l+r)>>1;
	build(i*2,l,mid);
	build(i*2+1,mid+1,r);
	tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
	tree[i].sum%=mod;
	return ;
}

inline void pushdown(int i){
	if(tree[i].tag!=0){
		tree[i*2].tag+=tree[i].tag;
		tree[i*2+1].tag+=tree[i].tag;
		int mid=(tree[i].l+tree[i].r)>>1;
		tree[i*2].sum+=tree[i].tag*(mid-tree[i].l+1);
		tree[i*2+1].sum+=tree[i].tag*(tree[i].r-mid);
		tree[i].tag=0;
	}
	return ;
}

inline void add(int i,int l,int r,int k){
	if(tree[i].l>=l&&tree[i].r<=r){
		tree[i].sum+=k*(tree[i].r-tree[i].l+1);
		tree[i].tag+=k;
		return ;
	}
	pushdown(i);
	if(tree[i*2].r>=l)
		add(i*2,l,r,k);
	if(tree[i*2+1].l<=r)
		add(i*2+1,l,r,k);
	tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
	tree[i].sum%=mod;
	return ;
}

inline int search(int i,int l,int r){
	if(tree[i].l>=l&&tree[i].r<=r)
		return tree[i].sum;
	if(tree[i].l>r||tree[i].r<l)
		return 0;
	int ans=0;
	if(tree[i*2].r>=l)
		ans+=search(i*2,l,r);
	if(tree[i*2+1].l<=r)
		ans+=search(i*2,l,r);
	ans%=mod;
	return ans;
}

inline void treeadd(int x,int y,int val){
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]])
			swap(x,y);
		add(1,idx[top[x]],idx[x],val);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y])
		swap(x,y);
	add(1,idx[x],idx[y],val);
}

inline void treesum(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]])
			swap(x,y);
		ans+=search(1,idx[top[x]],idx[x]);
		ans%=mod;
		x=fa[top[x]];
	}
	if(deep[x]>deep[y])
		swap(x,y);
	ans+=search(1,idx[x],idx[y]);
	ans%=mod;
	printf("%d\n",ans);
	return ;
}

inline void sonadd(ll x,ll val){
	add(1,idx[x],idx[x]+tot[x]-1,val);
	return ;
}

inline void sonsum(int x){
	printf("%d\n",search(1,idx[x],idx[x]+tot[x]-1)%mod);
	return ;
}

int main(){
	memset(head,-1,sizeof(head));
	scanf("%d%d%d%d",&n,&m,&r,&mod);
	for(int i=1;i<=n;i++)
		scanf("%d",&b[i]);
	for(int i=1;i<n;i++){
		ll x,y;
		scanf("%d%d",&x,&y);
		addpath(x,y);
		addpath(y,x);
	}
	dfs1(r,0,1);
	dfs2(r,r);
	build(1,1,n);
	while(m--){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&xx,&yy,&k);
			treeadd(xx,yy,k%mod);
		}
		if(op==2){
			scanf("%d%d",&xx,&yy);
			treesum(xx,yy);
		}
		if(op==3){
			scanf("%d%d",&xx,&k);
			sonadd(xx,k%mod);
		}
		if(op==4){
			scanf("%d",&xx);
			sonsum(xx);
		}
	}
	return 0;
}
2024/6/28 21:23
加载中...