树剖10pts,其它WA,第一个AC,调试了两天都还没有解决,希望得到高人指点
查看原帖
树剖10pts,其它WA,第一个AC,调试了两天都还没有解决,希望得到高人指点
110261
Seanocean楼主2021/11/26 20:13
#include<stdio.h>
#define ll long long
#define File(name) freopen(name".in","r",stdin);freopen(name".out","w",stdout);
const int N=1e5;
int n,m,r,P,id[N+1];

inline int Min(int a,int b){return a<b?a:b;}
inline int Max(int a,int b){return a>b?a:b;}
inline void Swap(int &a,int &b){int t=a;a=b;b=t;}

int head[N+1],num_edge;
struct Gragh{
	int to,next;
}edge[2*(N)];
void Add_edge(int from,int to) {edge[++num_edge]=(Gragh){to,head[from]};head[from]=num_edge;}

struct Node{
	int d,fa,sz,bs,t,top,w;
}p[N+1];
void Dfs1(int u,int fa,int deep)
{
	p[u].fa=fa,p[u].d=deep,p[u].sz=1;
	for(int i=head[u];i;i=edge[i].next)
	{
		if(edge[i].to!=fa)
		{
			Dfs1(edge[i].to,u,deep+1);
			p[u].sz+=p[edge[i].to].sz; 
			if(p[edge[i].to].sz>p[p[u].bs].sz) 
				p[u].bs=edge[i].to;
		}
	}
}
int index_t;
void Dfs2(int u,int top)
{
	p[u].t=++index_t,p[u].top=top;
	id[index_t]=u;
	if(!p[u].bs) return ;
	Dfs2(p[u].bs,top);
	for(int i=head[u];i;i=edge[i].next)
	{
		if(edge[i].to!=p[u].fa&&edge[i].to!=p[u].bs)
		{
			Dfs2(edge[i].to,edge[i].to);
		}
	}
}


struct Seg{
	int l,r,sum,add;
}t[4*(N+1)];
struct Ope{
	int l,r,w;
}modify,getsum;
void Build(int k,int l,int r)
{
	t[k].l=l,t[k].r=r;
	if(l==r)
	{
		t[k].sum=p[id[l]].w;
		return ;
	}
	int mid=(l+r)>>1;
	Build(k<<1,l,mid);
	Build(k<<1|1,mid+1,r);
	t[k].sum=t[k<<1].sum+t[k<<1|1].sum; 
}
void Modify(int k)
{
	if(t[k].l>modify.r||t[k].r<modify.l) return ;
	if(t[k].l>=modify.l&&t[k].r<=modify.r)
	{
		t[k].add+=modify.w;
		return;
	}
	t[k].sum+=(Min(t[k].r,modify.r)-Max(t[k].l,modify.l)+1)*modify.w;
	int mid=(t[k].l+t[k].r)>>1;
	if(modify.l<=mid) Modify(k<<1);
	if(modify.r>mid) Modify(k<<1|1);
}
ll Getsum(int k)
{
	if(getsum.l>t[k].r||getsum.r<t[k].l) return 0;
	if(t[k].l>=getsum.l&&t[k].r<=getsum.r) 
	{
		return (t[k].sum+((t[k].r-t[k].l+1)*t[k].add)%P)%P;
	}
	int mid=(t[k].l+t[k].r)>>1;
	ll res=((Min(t[k].r,getsum.r)-Max(t[k].l,getsum.l)+1)*t[k].add)%P;
	//通货是没有传递下去的,没有必要 
	if(getsum.l<=mid) res=(res+Getsum(k<<1))%P;
	if(getsum.r>mid) res=(res+Getsum(k<<1|1))%P;
	return res; 
} 
void Modify_path(int l,int r,ll w)
{
	while(p[l].top!=p[r].top)
	{
		if(p[l].d<p[r].d) Swap(l,r);
		modify=(Ope){p[p[l].top].t,p[l].t,w},Modify(1);
		l=p[p[l].top].fa;
	}
	if(p[l].d>p[r].d) Swap(l,r);
	modify=(Ope){p[l].t,p[r].t,w},Modify(1); 
}
inline ll Getsum_path(int l,int r)
{
	ll res=0;
	while(p[l].top!=p[r].top)
	{
		if(p[l].d<p[r].d) Swap(l,r);
		getsum=(Ope){p[p[l].top].t,p[l].t},res=(res+Getsum(1))%P;
		l=p[p[l].top].fa;
	}
	if(p[l].d>p[r].d) Swap(l,r);
	getsum=(Ope){p[l].t,p[r].t},res=(res+Getsum(1))%P;
	return res; 
} 
void Modify_subtree(int u,int w)
{
	modify=(Ope){p[u].t,p[u].t+p[u].sz-1,w},Modify(1);
}
inline ll Getsum_subtree(int u)
{
	getsum=(Ope){p[u].t,p[u].t+p[u].sz-1};return Getsum(1);
}
int main()
{
	//File("1");
	scanf("%d%d%d%d",&n,&m,&r,&P);
	ll fw;
	for(int i=1;i<=n;i++) scanf("%lld",&fw),p[i].w=fw%P;
	int from,to;
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&from,&to);
		Add_edge(from,to),Add_edge(to,from);
	}
	Dfs1(r,0,1);
	Dfs2(r,r); 
	int ty,l,r,w,tree;
	Build(1,1,n);
	for(int i=1;i<=m;i++)
	{
		scanf("%d",&ty);
		if(ty==1)
		{
			scanf("%d%d%lld",&l,&r,&w);
			Modify_path(l,r,w%P);
		}
		else if(ty==2)
		{
			scanf("%d%d",&l,&r); 
			printf("%d\n",Getsum_path(l,r));
		}
		else if(ty==3)
		{
			scanf("%d%lld",&l,&w); 
			Modify_subtree(l,w%P);
		}
		else
		{
			scanf("%d",&l);
			printf("%d\n",Getsum_subtree(l));
		}
	}
	return 0;
 }

2021/11/26 20:13
加载中...