树链剖分,只A了#1#4,蒟蒻求调
查看原帖
树链剖分,只A了#1#4,蒟蒻求调
570081
Hesan楼主2022/7/23 21:19

#include<bits/stdc++.h>
using namespace std;
int N,M,R,P;
int dw[100010];
vector<int> e[100010];
int fa[100010],dth[100010],hs[100010],siz[100010];
int dfn[100010],rsk[100010],top[100010];
long long tree[400010],tag[400010];
void dfs1(int x){
	int maxx=0;
	siz[x]++;dth[x]=dth[fa[x]]+1;
	for(int i=0;i<e[x].size();i++){
		int v=e[x][i];
		if(v==fa[x]) continue;
		fa[v]=x;dfs1(v);siz[x]+=siz[v];
		if(siz[v]>maxx){maxx=siz[v];hs[x]=v;}
	}
}
void dfs2(int x,int r){
	top[x]=r;dfn[x]=++dfn[0];rsk[dfn[0]]=x;
	if( hs[x] ) dfs2(hs[x],r);
	else return ; 
	for(int i=0;i<e[x].size();i++){
		int v=e[x][i];
		if(dfn[v]) continue;
		dfs2(v,v); 
	}
}
void build(int x,int l,int r){
	if(l==r){ tree[x]= dw[rsk[r]];return ;}
	int mid=(l+r)>>1;
	build((x<<1),l,mid);build((x<<1)+1,mid+1,r);
	tree[x]=tree[x<<1]+tree[(x<<1)+1];tree[x]%=P;
}
void update(int x,int l,int r,const int L,const int R,int k){
	if(L<=l && r<=R ){ tree[x]+=(r-l+1)*k%P;tree[x]%=P;tag[x]+=k;tag[x]%=P; return ;}
	int mid=(l+r)>>1;
	if(mid>=L) update(x<<1,l,mid,L,R,k);
	if(mid<R) update((x<<1)+1,mid+1,r,L,R,k);
	tree[x]=tree[x<<1]+tree[(x<<1)+1];tree[x]%=P;
}

void pushdown (int x,int l,int r){      			 //pushdown 下传懒标记 
	int ls=x<<1,rs=(x<<1)+1;
	int mid=(l+r)>>1,llen=mid-l+1,rlen=r-mid;
	tree[ls]+=tag[x]*llen%P;tree[ls]%=P;
	tree[rs]+=tag[x]*rlen%P;tree[rs]%=P;
	tag[ls]+=tag[x];tag[rs]+=tag[x];
	tag[ls]%=P;tag[rs]%=P;tag[x]=0;
}

int query(int x,int l,int r,int L,int R){

	if(L<=l && r<=R ) return tree[x];
	int res=0;
	if(tag[x]) pushdown(x,l,r);
	int mid=(l+r)>>1;
	if( L<=mid ) res+=query(x<<1,l,mid,L,R),res%=P;
	if( mid<R )  res+=query((x<<1)+1,mid+1,r,L,R),res%=P; 
	return res;
}

void op1(int x,int y,int z){
	while(top[x]!=top[y]){
		if(dth[top[x]]>dth[top[y]]){
			update(1,1,N,dfn[top[x]],dfn[x],z);
			x=fa[top[x]];
		}
		else{
			update(1,1,N,dfn[top[y]],dfn[y],z);
			y=fa[top[y]];
		}
	}
	if(dfn[x]<dfn[y]) update(1,1,N,dfn[x],dfn[y],z);
	else	update(1,1,N,dfn[y],dfn[x],z);
}
int op2(int x,int y){
	int res=0;
	while(top[x]!=top[y]){
		if(dth[top[x]]>dth[top[y]]){
			res+=query(1,1,N,dfn[top[x]],dfn[x]);
			x=fa[top[x]];
		}
		else{
			res+=query(1,1,N,dfn[top[y]],dfn[y]);
			y=fa[top[y]];
		}
		res%=P;
	}
	if(dfn[x]<dfn[y]) res+=query(1,1,N,dfn[x],dfn[y]);
	else	res+=query(1,1,N,dfn[y],dfn[x]);
	return res%P;
}



int main(){
	cin>>N>>M>>R>>P;
	for(int i=1;i<=N;i++) cin>>dw[i];
	int u,v;
	for(int i=1;i<N;i++) cin>>u>>v,e[u].push_back(v),e[v].push_back(u);
	dfs1(R);dfs2(R,R);build(1,1,N);
	while(M--){
		int op,x,y,z;cin>>op;
		if(op==1) {cin>>x>>y>>z;op1(x,y,z%P);}
		if(op==2) {cin>>x>>y; cout<<op2(x,y)<<endl;}
		if(op==3) {cin>>x>>z;update(1,1,N,dfn[x],dfn[x]+siz[x]-1,z%P); }
		if(op==4) {cin>>x; cout<<query(1,1,N,dfn[x],dfn[x]+siz[x]-1)<<endl;}
	}
	return 0;
}
2022/7/23 21:19
加载中...