蒟蒻求助,刚学OI,样例WA了
查看原帖
蒟蒻求助,刚学OI,样例WA了
247359
WuhenGSL楼主2020/8/20 11:35

样例输出第二个值是9

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 100010
#define ll long long
using namespace std;
ll n,t,r,p,X,Y,Z; 
ll Root[N],Next[N<<1],v[N<<1],cnt=0;
ll d[N],a[N],id[N],cur[N],fa[N],son[N],size[N],top[N],tot=0;
struct node{
	ll l,r,sum,tag;
}c[N<<2];
inline void add(ll _u,ll _v)
{
	v[++cnt]=_v;
	Next[cnt]=Root[_u];
	Root[_u]=cnt;
}
void dfs1(ll u)
{
	size[u]=1;
	for(ll x=Root[u];x!=0;x=Next[x])
		if(v[x]!=fa[u]){
			d[v[x]]=d[u]+1,fa[v[x]]=u;//初始化d和fa 
			dfs1(v[x]),size[u]+=size[v[x]];//遍历子树, 更新size 
			if(size[v[x]]>size[son[u]])son[u]=v[x];//更新重儿子 
		}
}
void dfs2(ll u,ll t)
{
	id[u]=++tot/*时间戳*/,cur[tot]=a[u],top[u]=t;//将u加入dfs序 
	if(son[u])dfs2(son[u],t);//先处理重儿子 
	for(ll x=Root[u];x!=0;x=Next[x])//处理其他轻儿子, 轻儿子自己做重链头 
		if(v[x]!=fa[u]&&v[x]!=son[u])
			dfs2(v[x],v[x]);
}
void update(ll x)
{
	c[x].sum=(c[x<<1].sum+c[x<<1|1].sum)%p;
}
void pushdown(ll x){
	if(c[x].tag){
		c[x<<1].sum=(c[x<<1].sum+c[x].tag*(c[x<<1].r-c[x<<1].l+1))%p;
		c[x<<1|1].sum=(c[x<<1|1].sum+c[x].tag*(c[x<<1|1].r-c[x<<1|1].l+1))%p;
		c[x<<1].tag=(c[x<<1].tag+c[x].tag)%p;
		c[x<<1|1].tag=(c[x<<1|1].tag+c[x].tag)%p;
		c[x].tag=0;
	}
}
void build(ll l,ll r,ll x)
{
	c[x].l=l,c[x].r=r;
	if(l==r){
		c[x].sum=cur[x];
		return;
	}
	ll mid=(l+r)>>1;
	build(l,mid,x<<1);
	build(mid+1,r,x<<1|1);
	update(x);
}
ll query(ll l,ll r,ll x)
{
	if(c[x].l>=l&&c[x].r<=r)
		return c[x].sum;
	pushdown(x);
	ll mid=(c[x].l+c[x].r)>>1;
	ll ans=0;
	if(l<=mid)ans=(ans+query(l,r,x<<1))%p;
	if(r>mid)ans=(ans+query(l,r,x<<1|1))%p;
	return ans%p;
}
void change(ll l,ll r,ll z,ll x)
{
	if(c[x].l>=l&&c[x].r<=r){
		c[x].sum+=z*(c[x].r-c[x].l+1);
		c[x].tag+=z;
		return;
	}
	pushdown(x);
	ll mid=(c[x].l+c[x].r)>>1;
	if(l<=mid)change(l,r,x<<1,z);
	if(r>mid)change(l,r,x<<1|1,z);
	update(x);
}
inline ll calsum(ll x,ll y)
{
	ll res=0;
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]])
			swap(x,y);
			res=(res+query(id[top[x]],id[x],1))%p;
			x=fa[top[x]];
	}
	if(d[x]>d[y])swap(x,y);
	res=(res+query(id[x],id[y],1))%p;
	return res;
}
inline void treeadd(ll x,ll y,ll z)
{
	while(top[x]!=top[y]){
		if(d[top[x]]<d[top[y]])
			swap(x,y);
		change(id[top[x]],id[x],z,1);
		x=fa[top[x]];
	}
	if(d[x]>d[y])swap(x,y);
	change(id[x],id[y],z,1);
}
int main()
{
	scanf("%lld%lld%lld%lld",&n,&t,&r,&p);
	for(ll i=1;i<=n;++i)scanf("%lld",&a[i]);
	for(ll i=1;i<=n-1;++i){
		scanf("%lld%lld",&X,&Y);
		add(X,Y),add(Y,X);
	}
	dfs1(r);
	dfs2(r,r);
	build(1,n,1);
	while(t--){
		int opt;
		scanf("%d",&opt);
		if(opt==1){
			scanf("%lld%lld%lld",&X,&Y,&Z);
			treeadd(X,Y,Z%p);
		}
		if(opt==2){
			scanf("%lld%lld",&X,&Y);
			printf("%lld\n",calsum(X,Y)%p);
		}
		if(opt==3){
			scanf("%lld%lld",&X,&Z);
			change(id[X],id[X]+size[X]-1,Z%p,1);
		}
		if(opt==4){
			scanf("%lld",&X);
			printf("%lld\n",query(id[X],id[X]+size[X]-1,1)%p);
		}
	}
	return 0;
}
2020/8/20 11:35
加载中...