Mn-Zn刚学OI
  • 板块灌水区
  • 楼主W_Y_Z
  • 当前回复13
  • 已保存回复13
  • 发布时间2020/12/1 19:06
  • 上次更新2023/11/5 06:57:34
查看原帖
Mn-Zn刚学OI
122720
W_Y_Z楼主2020/12/1 19:06

求助树链剖分,改自闭了

#include<bits/stdc++.h>
using namespace std;  
inline int read(){
	int x=0; char ch=getchar();
	while(ch<'0'||ch>'9') { ch=getchar(); }
	while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x;
}	
inline int max(const int x,const int y) { return x>y?x:y; }
inline int min(const int x,const int y) { return x<y?x:y; }
const int maxn=1e5+5;
int n,m,r,mod;
int c[maxn];
int cnt_edge=0,a[maxn<<1],nxt[maxn<<1],head[maxn];
int fa[maxn],dep[maxn],siz[maxn],hs[maxn];
int top[maxn],cnt_clock=0,mc[maxn],id[maxn];
int tag[maxn<<2],sum[maxn<<2];
inline void addline(const int x,const int y){
	a[++cnt_edge]=y,nxt[cnt_edge]=head[x],head[x]=cnt_edge;
}
inline void push_up(const int i){
	sum[i]=(sum[i<<1]+sum[i<<1|1])%mod;
}
inline void push_down(const int i,const int len){
	if(tag[i]){
		sum[i<<1]=(sum[i<<1]+(len-(len>>1))*tag[i])%mod;
		sum[i<<1|1]=(sum[i<<1|1]+(len>>1)*tag[i])%mod;
		tag[i<<1]=(tag[i<<1]+tag[i])%mod;
		tag[i<<1|1]=(tag[i<<1|1]+tag[i])%mod;
		tag[i]=0;
	}
}
void update(const int i,const int l,const int r,const int L,const int R,const int k){
	if(L<=l&&r<=R) {
		sum[i]=sum[i]+(r-l+1)*k;
		tag[i]=tag[i]+k;
		return ;
	}
	push_down(i,r-l+1);
	int mid=l+r>>1;
	if(L<=mid) update(i<<1,l,mid,L,R,k);
	if(R>mid) update(i<<1|1,mid+1,r,L,R,k);
	push_up(i);
}
int query(const int i,const int l,const int r,const int L,const int R){
	if(L<=l&&r<=R) {
		return sum[i]%mod;
	}
	push_down(i,r-l+1);
	int mid=l+r>>1,res=0;
	if(L<=mid) res+=(res+query(i<<1,l,mid,L,R))%mod;
	if(R>mid) res+=(res+query(i<<1|1,mid+1,r,L,R))%mod;
	return res;
}
void build(const int i,const int l,const int r){
	if(l==r){
		sum[i]=mc[l]%mod;
		return ;
	}
	int mid=l+r>>1;
	build(i<<1,l,mid);
	build(i<<1|1,mid+1,r);
	push_up(i);
}
void dfs1(int u,int pre){
	fa[u]=pre,dep[u]=dep[pre]+1,siz[u]=1;
	for(register int p=head[u];p;p=nxt[p]){
		int v=a[p];
		if(v==pre) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[hs[u]]) hs[u]=v;
	}
}
void dfs2(int u,int tf){
	top[u]=tf,id[u]=++cnt_clock,mc[cnt_clock]=c[u];
	if(!hs[u]) return ;
	dfs2(hs[u],tf);
	for(register int p=head[u];p;p=nxt[p]){
		int v=a[p];
		if(v==fa[u]||v==hs[u]) continue;
		dfs2(v,v);
	}
}
inline void updson(int x,int k){
	update(1,1,n,id[x],id[x]+siz[x]-1,k);
}
inline int qson(int x){
	return query(1,1,n,id[x],id[x]+siz[x]-1);
}
inline void updrange(int x,int y,int k){
	k%=mod;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		update(1,1,n,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	update(1,1,n,id[x],id[y],k);
} 
inline int qrange(int x,int y){
	int res=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		res=(res+query(1,1,n,id[top[x]],id[x]))%mod;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	res=(res+query(1,1,n,id[x],id[y]))%mod;
	return res;
} 
signed main(void){
	n=read(),m=read(),r=read(),mod=read();
	for(int i=1;i<=n;++i) c[i]=read();
	for(int i=1;i<n;++i){
		int u=read(),v=read();
		addline(u,v),addline(v,u);
	}
	dfs1(r,0);
	dfs2(r,r);
	build(1,1,n);
//	for(int i=1;i<=n;++i)
//    	cout<<c[i]<<' '<<fa[i]<<' '<<dep[i]<<' '<<siz[i]<<' '<<hs[i]<<' '<<id[i]<<' '<<mc[i]<<' '<<top[i]<<' '<<endl;
	for(int i=1;i<=m;++i){
		int flag=read();
		if(flag==1){
			int x=read(),y=read(),z=read();
			updrange(x,y,z);
		}
		else if(flag==2){
			int x=read(),y=read();
			printf("%lld\n", qrange(x,y));
		}
		else if(flag==3){
			int x=read(),z=read();
			updson(x,z);
		}
		else if(flag==4){
			int x=read();
			printf("%lld\n", qson(x));
		}
	}
	return 0;
} 
2020/12/1 19:06
加载中...