求助,P3384树链剖分模板
  • 板块灌水区
  • 楼主zuishuai
  • 当前回复4
  • 已保存回复4
  • 发布时间2021/10/29 17:07
  • 上次更新2023/11/4 02:00:20
查看原帖
求助,P3384树链剖分模板
515001
zuishuai楼主2021/10/29 17:07
#include<bits/stdc++.h>
#define N 100005
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
inline void write(int x){
	int tmp=x<0?-x:x,cnt=0;char f[200];
	if(!x)
		putchar('0');
	if(x<0)
		putchar('-');
	while(tmp){
		f[cnt++]=tmp%10+'0';
		tmp/=10;
	}
	while(cnt)
		putchar(f[--cnt]);
	putchar('\n');
}
int n,x,y,flag,z,mod,q,root,tp[N],id[N],t,ans;
int L,R,b[N<<3],tag[N<<3],v[N];
int head[N],nxt[N<<1],to[N],p;
int dep[N],f[N],sz[N],son[N],W[N];
inline void Build(int u,int v){
	nxt[++p]=head[u];head[u]=p;to[p]=v;
	nxt[++p]=head[v];head[v]=p;to[p]=u;
}
void dfs1(int k,int fa,int deep){
	dep[k]=deep++;
	f[k]=fa;
	sz[k]=1;
	for(int i=head[k];i;i=nxt[i])
		if(to[i]!=fa){
			dfs1(to[i],k,deep);
			sz[k]+=sz[to[i]];
			if(sz[to[i]]>sz[son[k]])
				son[k]=to[i];
		}
}
void dfs2(int k,int top){
	id[k]=++t;
	W[t]=v[k];
	tp[k]=top;
	if(!son[k])
		return;
	dfs2(son[k],top);
	for(int i=head[k];i;i=nxt[i])
		if(to[i]!=f[k]&&to[i]!=son[k])
			dfs2(to[i],to[i]);
}
inline int ls(int w){
	return w<<1;
}
inline int rs(int w){
	return w<<1|1;
}
inline void push_up(int w){
	b[w]=(b[ls(w)]+b[rs(w)])%mod;
}
void build(int w,int l,int r){
	if(l==r){
		b[w]=W[l];
		return;
	}
	int mid=(l+r)>>1;
	build(ls(w),l,mid);
	build(rs(w),mid+1,r);
	push_up(w);
}
inline void push_down(int w,int l,int r){
//	cout<<w<<" ";
	int mid=(l+r)>>1;
	b[ls(w)]=(b[ls(w)]+tag[w]*(mid-l+1)%mod)%mod;
	b[rs(w)]=(b[rs(w)]+tag[w]*(r-mid)%mod)%mod;
	tag[ls(w)]+=tag[w];
	tag[rs(w)]+=tag[w];
	tag[w]=0;
}
void query(int w,int l,int r){
	if(L<=l&&R>=r){
		ans=(ans+b[w])%mod;
		return;
	}
	int mid=(l+r)>>1;
	if(tag[w])
		push_down(w,l,r);
	if(L<=mid)
		query(ls(w),l,mid);
	if(R>mod)
		query(rs(w),mid+1,r);
}
void update(int w,int l,int r){
	if(L<=l&&R>=r){
		b[w]=(b[w]+(r-l+1)*z%mod)%mod;
		tag[w]+=z;
		return;
	}
	int mid=(l+r)>>1;
	if(tag[w])
		push_down(w,l,r);
	if(L<=mid)
		update(ls(w),l,mid);
	if(R>mid)
		update(rs(w),mid+1,r);
	push_up(w);
}
void findup(){
	while(tp[x]!=tp[y]){
		if(dep[tp[x]]<dep[tp[y]])
			swap(x,y);
		L=id[tp[x]];
		R=id[x];
		update(1,1,n);
		x=f[tp[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	L=id[x];
	R=id[y];
	update(1,1,n);
}
int findqu(){
	int res=0;
	while(tp[x]!=tp[y]){
		if(dep[tp[x]]<dep[tp[y]])
			swap(x,y);
		L=id[tp[x]];
		R=id[x];
		ans=0;
		query(1,1,n);
		res=(res+ans)%mod;
		x=f[tp[x]];
	}
	if(dep[x]>dep[y])
		swap(x,y);
	L=id[x];
	R=id[y];
	ans=0;
	query(1,1,n);
	res=(res+ans)%mod;
	return res;
}
int main(){
	n=read();q=read();root=read();mod=read();
	for(register int i=1;i<=n;i++)
		v[i]=read()%mod;
	for(int i=1;i<n;i++)
		Build(read(),read());
	dfs1(root,0,1);
	dfs2(root,root);
	build(1,1,n);
	while(q--){
		flag=read();
		if(flag==1){
			x=read();y=read();z=read()%mod;
			findup();
		}
		if(flag==2){
			x=read();y=read();
			write(findqu());
		}
		if(flag==3){
			x=read();z=read()%mod;
			L=id[x];
			R=id[x]+sz[x]-1;
			update(1,1,n);
		}
		if(flag==4){
			x=read();
			L=id[x];
			R=id[x]+sz[x]-1;
			ans=0;
			query(1,1,n);
			write(ans);
		}
	}
	return 0;
}

板子题打了一下午,我还是太蒻了……

2021/10/29 17:07
加载中...