树剖没过样例求助
查看原帖
树剖没过样例求助
280473
404Not_Found楼主2021/9/10 13:03

RT,样例输出 2,72,7

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100005
struct edge{
	int to,next;
} e[MAXN<<1];
int head[MAXN],cnt;
inline void add(int u,int v)
{
	e[++cnt].to=v; e[cnt].next=head[u]; head[u]=cnt;
}
//树剖 
int top[MAXN],siz[MAXN],fa[MAXN],depth[MAXN],son[MAXN],id[MAXN],a[MAXN],w[MAXN],idx;
void dfs1(int u,int fath,int dep)
{
	fa[u]=fath; depth[u]=dep; siz[u]=1;
	int maxson=-1;
	for(int i=head[u];i;i=e[i].next)
	{
		int v=e[i].to;
		if(v==fath) continue;
		dfs1(v,u,dep+1);
		siz[u]+=siz[v];
		if(siz[v]>maxson){maxson=siz[v]; son[u]=v;}
	}
}
void dfs2(int u,int tp)
{
	id[u]=++idx; top[u]=tp; w[cnt]=a[u];
	if(!son[u]) return;
	dfs2(son[u],tp);
	for(int i=head[u];i;i=e[i].next)
	{
		int v=e[i].to;
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}
//线段树 
int n,m,rt,mod;
int tree[MAXN<<2],tag[MAXN<<2];
inline void push_up(int p){ tree[p]=(tree[p<<1]+tree[p<<1|1])%mod;}
void build(int p,int l,int r)
{
	if(l==r){ tree[p]=w[l];return;}
	int mid=(l+r)>>1;
	build(p<<1,l,mid); build(p<<1|1,mid+1,r);
	push_up(p);
}
inline void push_down(int p,int l,int r)
{
	if(tag[p])
	{
		int mid=(l+r)>>1;
		tag[p<<1]=(tag[p<<1]+tag[p])%mod;
		tag[p<<1|1]=(tag[p<<1|1]+tag[p])%mod;
		tree[p<<1]=(tree[p<<1]+(mid-l+1)*tag[p])%mod;
		tree[p<<1|1]=(tree[p<<1|1]+(r-mid)*tag[p])%mod;
		tag[p]=0;
	}
}
void update(int p,int l,int r,int L,int R,int k)
{
	if(L<=l&&r<=R){tree[p]=(tree[p]+k*(r-l+1))%mod; tag[p]=(tag[p]+k)%mod; return;};
	push_down(p,l,r);
	int mid=(l+r)>>1;
	if(L<=mid) update(p<<1,l,mid,L,R,k);
	if(mid<R) update(p<<1|1,mid+1,r,L,R,k);
	push_up(p);
}
int query(int p,int l,int r,int L,int R)
{
	if(L<=l&&r<=R) return tree[p];
	push_down(p,l,r);
	int mid=(l+r)>>1,res=0;
	if(L<=mid) res=(res+query(p<<1,l,mid,L,R))%mod;
	if(mid<R) res=(res+query(p<<1|1,mid+1,r,L,R))%mod;
	return res; 
}
//树剖操作 
inline int range_query(int u,int v)
{
	int res=0;
	while(top[u]^top[v])
	{
		if(depth[top[u]]<depth[top[v]]) swap(u,v);
		res=(res+query(1,1,n,id[top[u]],id[u]));
		u=fa[top[u]];
	}
	if(depth[u]>depth[v]) swap(u,v);
	res=(res+query(1,1,n,id[u],id[v]))%mod;
	return res;
}
inline int query_son(int u){return query(1,1,n,id[u],id[u]+siz[u]-1);}
inline void range_update(int u,int v,int k)
{
	k%=mod;
	while(top[u]^top[v])
	{
		if(depth[top[u]]<depth[top[v]]) swap(u,v);
		update(1,1,n,id[top[u]],id[u],k);
		u=fa[top[u]];
	}
	if(depth[u]>depth[v]) swap(u,v);
	update(1,1,n,id[u],id[v],k);
}
inline void update_son(int u,int k){update(1,1,n,id[u],id[u]+siz[u]-1,k);}
inline int read()
{
	int x=0,f=1; char c=getchar();
	for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
	for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+c-48;
	return x*f; 
}
int main()
{
	n=read(); m=read(); rt=read(); mod=read();
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		add(u,v); add(v,u);
	}
	dfs1(rt,0,1);
	dfs2(rt,rt);
	build(1,1,n);
	while(m--)
	{
		int opt=read(),x,y,k;
		switch(opt)
		{
			case 1:
				x=read(); y=read(); k=read();
				range_update(x,y,k);
				break;
			case 2:
				x=read(); y=read();
				printf("%d\n",range_query(x,y));
				break;
			case 3:
				x=read(); y=read();
				update_son(x,y);
				break;
			case 4:
				x=read();
				printf("%d\n",query_son(x));
				break;
		}
	}
	return 0;
}
2021/9/10 13:03
加载中...