求助树剖板子
查看原帖
求助树剖板子
141577
yhc12345楼主2021/7/7 10:18

提交10分,其他全WA了,检查了很久都没查出来

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define INF 0x3f3f3f3f
#define int long long
using namespace std;
typedef long long ll;
const int N=1e5+10;
int n,m,r,p,a[N];
int head[N],ne;
struct Edge {
	int v,nxt;
}e[N<<1];
struct Tree {
	int l,r,sum,add;
}t[N<<2];
void init() {
	memset(head,-1,sizeof(head));
	ne=0;
}
void add_edge(int u,int v) {
	e[ne].v=v;
	e[ne].nxt=head[u];
	head[u]=ne++;
}
int dep[N],son[N],size[N],top[N],fa[N],rnk[N],dfn[N],cnt;
void dfs1(int x,int pre) {
	fa[x]=pre;
	size[x]=1;
	dep[x]=dep[pre]+1;
	for(int i=head[x];i!=-1;i=e[i].nxt) {
		int v=e[i].v;
		if(v==pre) continue;
		dfs1(v,x);
		size[x]+=size[v];
		if(size[v]>size[son[x]]) son[x]=v;
	}
}
void dfs2(int x,int pre) {
	dfn[++cnt]=x;
	rnk[x]=cnt;
	top[x]=pre;
	if(!son[x]) return;
	dfs2(son[x],pre);
	for(int i=head[x];i!=-1;i=e[i].nxt) {
		int v=e[i].v;
		if(v==fa[x]||v==son[x]) continue;
		dfs2(v,v);
	}
}
void pushup(int rt) {
	t[rt].sum=t[rt<<1].sum+t[rt<<1|1].sum;
}
void build(int rt,int l,int r) {
	t[rt].l=l;
	t[rt].r=r;
	if(l==r) {
		t[rt].sum=a[dfn[l]];
		return;
	}
	int mid=(l+r)>>1;
	build(rt<<1,l,mid);
	build(rt<<1|1,mid+1,r);
	pushup(rt);
}
void pushdown(int rt) {
	if(t[rt].add==0) return;
	t[rt<<1].sum+=(t[rt<<1].r-t[rt<<1].l+1)*t[rt].add;
	t[rt<<1].sum%=p;
	t[rt<<1|1].sum+=(t[rt<<1|1].r-t[rt<<1|1].l+1)*t[rt].add;
	t[rt<<1|1].sum%=p;
	t[rt<<1].add+=t[rt].add;
	t[rt<<1].sum%=p;
	t[rt<<1|1].add+=t[rt].add;
	t[rt<<1|1].sum%=p;
	t[rt].add=0;
}
void update(int rt,int L,int R,int v) {
	if(L<=t[rt].l&&t[rt].r<=R) {
		t[rt].sum+=v*(t[rt].r-t[rt].l+1);
		t[rt].sum%=p;
		t[rt].add+=v;
		t[rt].add%=p;
		return;
	}
	pushdown(rt);
	int mid=(t[rt].l+t[rt].r)>>1;
	if(L<=mid) {
		update(rt<<1,L,R,v);
	}
	if(R>mid) {
		update(rt<<1|1,L,R,v);
	}
}
int query(int rt,int L,int R) {
	if(L<=t[rt].l&&t[rt].r<=R) {
		return t[rt].sum;
	}
	pushdown(rt);
	int mid=(t[rt].l+t[rt].r)>>1,ret=0;
	if(L<=mid) {
		ret+=query(rt<<1,L,R);
		ret%=p;
	}
	if(R>mid) {
		ret+=query(rt<<1|1,L,R);
		ret%=p;
	}
	return ret;
}
void tree_update(int x,int y,int z) {
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,rnk[top[x]],rnk[x],z);
		x=fa[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	update(1,rnk[y],rnk[x],z);
}
int tree_query(int x,int y) {
	int ret=0;
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ret+=query(1,rnk[top[x]],rnk[x]);
		ret%=p;
		x=fa[top[x]];
	}
	if(dep[x]<dep[y]) swap(x,y);
	ret+=query(1,rnk[y],rnk[x]);
	ret%=p;
	return ret;
}
signed main() {
	init();
	scanf("%lld%lld%lld%lld",&n,&m,&r,&p);
	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
	for(int i=1;i<n;i++) {
		int u,v;
		scanf("%lld%lld",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs1(r,r);
	dfs2(r,r);
	build(1,1,n);
	while(m--) {
		int op,x,y,z;
		scanf("%lld",&op);
		if(op==1) {
			scanf("%lld%lld%lld",&x,&y,&z);
			tree_update(x,y,z);
		}
		else if(op==2) {
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",tree_query(x,y));
		}
		else if(op==3) {
			scanf("%lld%lld",&x,&z);
			update(1,rnk[x],rnk[x]+size[x]-1,z);
		}
		else {
			scanf("%lld",&x);
			printf("%lld\n",query(1,rnk[x],rnk[x]+size[x]-1));
		}
	}
	return 0;
}
2021/7/7 10:18
加载中...