求调
查看原帖
求调
530915
翟翟楼主2024/1/13 20:29
#include<bits/stdc++.h>
typedef long long ll;
namespace IO{
	static const int bsize=1000000;
	static unsigned char buf[bsize];
	static int len,pos;
	bool isEOF(){
		if(pos==len){
			pos=0;
			len=fread(buf,1,bsize,stdin);
			if(pos==len)return 1;
		}
		return 0;
	}
	char gc(){
		return isEOF()?EOF:buf[pos++];
	}
	int rint(){
		int x=0;
		char c=gc();
		for(;c<48||c>57;c=gc());
		for(;c>=48&&c<=57;c=gc())
			x=(x<<1)+(x<<3)+(c^48);
		return x;
	}
	template<typename T>
	void read(T&x){x=rint();}
	template<typename T,typename...Ts>
	inline void read(T&x,Ts&...rest){
		read(x);
		read(rest...);
	}
}
using IO::read;
using namespace std;
const int N=1e5+1,M=2e5+1;
int n,m,r,p,o,u,v,w,dfn[N],cnt;
int sz[N],zz[N],top[N],fat[N],dep[N];
int s[N<<2],ad[N<<2];
int tot,head[N],to[M],nxt[M];
void add(int u,int v){
	nxt[++tot]=head[u];
	head[u]=tot;
	to[tot]=v;
}
#define lc k<<1
#define rc k<<1|1
void addtag(int k,int l,int r,int d){
	(ad[k]+=d)%=p;
	(s[k]+=1ll*(r-l+1)*d%p)%=p;
}
void pushdown(int k,int l,int r,int mid){
	if(!ad[k])return;
	addtag(lc,l,mid,ad[k]);
	addtag(rc,mid+1,r,ad[k]);
	ad[k]=0;
}
void pushup(int k){
	s[k]=(s[lc]+s[rc])%p;
}
void build(int k,int l,int r){
	if(l==r){
		read(s[k]);s[k]%=p;
		return;
	}
	int mid=(l+r)>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(k);
}
void modify(int k,int l,int r,int x,int y,int w){
	if(x<=l&&r<=y){
		addtag(k,l,r,w);
		return;
	}
	if(y<l||x>r)return;
	int mid=(l+r)>>1;
	pushdown(k,l,r,mid);
	modify(lc,l,mid,x,y,w);
	modify(rc,mid+1,r,x,y,w);
	pushup(k);
}
int query(int k,int l,int r,int x,int y){
	if(x<=l&&r<=y)return s[k];
	if(l>y||r<x)return 0;
	int mid=(l+r)>>1;
	pushdown(k,l,r,mid);
	return (query(lc,l,mid,x,y)+query(rc,mid+1,r,x,y))%p;
}
void dfs1(int u,int fa){
	fat[u]=fa;
	dep[u]=dep[fa]+1;
	dfn[u]=++cnt;
	sz[u]=1;
	int w=0;
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fa)continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(!w||sz[v]>sz[w])w=v;
	}
	zz[u]=w;
}
void dfs2(int u,int t){
	top[u]=t;
	if(zz[u])dfs2(zz[u],t);
	for(int i=head[u];i;i=nxt[i]){
		int v=to[i];
		if(v==fat[u]||v==zz[u])continue;
		dfs2(v,v);
	}
}
void modifyr(int u,int v,int w){
	for(;top[u]!=top[v];){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		modify(1,1,n,dfn[top[u]],dfn[u],w);
		u=fat[top[u]];
	}
	if(dep[u]>dep[v])swap(u,v);
	modify(1,1,n,dfn[u],dfn[v],w);
}
int queryr(int u,int v){
	int res=0;
	for(;top[u]!=top[v];){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		(res+=query(1,1,n,dfn[top[u]],dfn[u]))%=p;
		u=fat[top[u]];
	}
	if(dep[u]>dep[v])swap(u,v);
	return (res+query(1,1,n,dfn[u],dfn[v]))%p;
}
int main(){
	read(n,m,r,p);
	build(1,1,n);
	for(int i=1;i<n;++i){
		read(u,v);
		add(u,v);
		add(v,u);
	}
	dfs1(r,0);
	dfs2(r,r);
	for(;m--;){
		read(o);
		if(o==1){
			read(u,v,w);
			modifyr(u,v,w);
		}
		else if(o==2){
			read(u,v);
			printf("%d\n",queryr(u,v));
		}
		else if(o==3){
			read(u,w);
			modify(1,1,n,dfn[u],dfn[u]+sz[u]-1,w);
		}
		else{
			read(u);
			printf("%d\n",query(1,1,n,dfn[u],dfn[u]+sz[u]-1));
		}
	}
	return 0;
}

样例我输出

2
18
2024/1/13 20:29
加载中...