MnZn刚学树剖1ms,求助
查看原帖
MnZn刚学树剖1ms,求助
549499
Disjoint_cat楼主2022/11/19 15:26

样例过了,交上去10分(AC #4)

#include<bits/stdc++.h>
#define ll long long
#define YJL_DRC_LCH_WJY_WQY_ZZH using
#define AK namespace
#define IOI std
#define Edge(x) for(int I=head[x];I;I=nxt[I])
YJL_DRC_LCH_WJY_WQY_ZZH AK IOI;
const int N=100005;
int n,m,root,u,v,op,x,y;
ll MOD,a[N],qz[N],z;
int head[N],to[N<<1],nxt[N<<1],tot;
void add(int Fr,int To){to[++tot]=To,nxt[tot]=head[Fr],head[Fr]=tot;}
int fa[N],top[N],dfn[N],siz[N],dep[N],son[N],Dfn;
struct SGT
{
#define lid id<<1
#define rid (lid)|1
	struct tree
	{
		int l,r;
		ll sum,lz;
	}tr[N<<2];
	void pu(int id)
	{
		tr[id].sum=(tr[lid].sum+tr[rid].sum)%MOD;
	}
	void pd(int id)
	{
		tree &now=tr[id];
		ll &lz=now.lz;
		if(!lz)return;
		now.sum=(now.sum+now.lz*(now.r-now.l+1))%MOD;
		tr[lid].lz+=lz,tr[rid].lz+=lz;
		tr[lid].lz%=MOD,tr[rid].lz%=MOD;
		lz=0;
	}
	void build(int l,int r,int id)
	{
		tr[id].l=l,tr[id].r=r,tr[id].lz=0;
		if(l==r)return tr[id].sum=qz[l],void();
		int mid=l+r>>1;
		build(l,mid,lid);
		build(mid+1,r,rid);
		pu(id);
	}
	void mdf(int l,int r,int id)
	{
		if(tr[id].l==l&&tr[id].r==r)
			return tr[id].lz=(tr[id].lz+z)%MOD,void();
		pd(id);
		if(tr[lid].r>=l)
			if(tr[rid].l<=r)
				mdf(l,tr[lid].r,lid),mdf(tr[rid].l,r,rid);
			else mdf(l,r,lid);
		else mdf(l,r,rid);
	}
	ll query(int l,int r,int id)
	{
		tree &now=tr[id];
		if(now.l==l&&now.r==r)return (now.sum+now.lz*(r-l+1))%MOD;
		pd(id);
		if(tr[lid].r>=l)
			if(tr[rid].l<=r)
				return (query(l,tr[lid].r,lid)+query(tr[rid].l,r,rid)\
				)%MOD;
			else return query(l,r,lid);
		return query(l,r,rid);
	}
}sgt;
void dfs1(int now,int Fa,int Dep)
{
	fa[now]=Fa,dep[now]=Dep,siz[now]=1;
	int masiz=0;
	Edge(now)
	{
		int t=to[I];
		if(t!=Fa)
		{
			dfs1(t,now,Dep+1);
			if(siz[t]>masiz)masiz=siz[t],son[now]=t;
			siz[now]+=siz[t];
		}
	}
}
void dfs2(int now,int Top)
{
	top[now]=Top,dfn[now]=++Dfn,qz[Dfn]=a[now];
	if(!son[now])return;
	dfs2(son[now],Top);
	Edge(now)
	{
		int t=to[I];
		if(t!=fa[now]&&t!=son[now])dfs2(t,t);
	}
}
void Lmdf()//link add
{
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		sgt.mdf(dfn[top[x]],dfn[x],1);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y])swap(x,y);
	sgt.mdf(dfn[y],dfn[x],1);
}
ll Lquery()//link query
{
	ll ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		ans=(ans+sgt.query(dfn[top[x]],dfn[x],1))%MOD;
		x=fa[top[x]];
	}
	if(dep[x]<dep[y])swap(x,y);
	ans=(ans+sgt.query(dfn[y],dfn[x],1))%MOD;
	return ans;
}
void Tmdf()//tree add
{
	sgt.mdf(dfn[x],dfn[x]+siz[x]-1,1);
}
ll Tquery()//tree query
{
	return sgt.query(dfn[x],dfn[x]+siz[x]-1,1);
}
int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	cin>>n>>m>>root>>MOD;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<n;i++)
	{
		cin>>u>>v;
		add(u,v),add(v,u);
	}
	dfs1(root,0,1);
	dfs2(root,root);
	sgt.build(1,n,1);
	while(m--)
	{
		cin>>op;
		switch(op)
		{
			case 1:cin>>x>>y>>z;Lmdf();break;
			case 2:cin>>x>>y;cout<<Lquery()<<endl;break;
			case 3:cin>>x>>z;Tmdf();break;
			case 4:cin>>x;cout<<Tquery()<<endl;
		}
	}
	return 0;
}
2022/11/19 15:26
加载中...