蒟蒻只过样例,求调。。。
查看原帖
蒟蒻只过样例,求调。。。
673643
GameFreak楼主2022/8/19 18:50

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>
inline T Min(T x,T y){
	return x<y?x:y;
}
template<class T>
inline T Max(T x,T y){
	return y<x?x:y;
}
template<class T>
inline void Swap(T &x,T &y){
	T tmp=x;
	x=y,y=tmp;
}
inline int read(){
	int x=0,f=1;char ch=getchar();
	while('0'>ch||'9'<ch){if(ch=='-') f=-f;ch=getchar();}
	while('0'<=ch&&'9'>=ch){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
const int MAXN=100005;
struct LS{
	int HEAD[MAXN],nxt[MAXN<<2],edge[MAXN<<2],tot;
	inline void add(int u,int v){
		edge[++tot]=v,nxt[tot]=HEAD[u],HEAD[u]=tot;
	}
	inline int head(int u){
		return HEAD[u];
	}
	inline int nex(int i){
		return nxt[i];
	}
	inline int operator[](int i){
		return edge[i];
	}
	inline void clear(){
		memset(HEAD,0,sizeof HEAD);
		tot=0;
	}
};
LS G;
int arr[MAXN];
int n=read(),m=read(),root=read(),M=read();
int siz[MAXN],son[MAXN],fa[MAXN],dep[MAXN];
inline void dfs1(int u){
	siz[u]=1,son[u]=-1;
	for(int i=G.head(u);i;i=G.nex(i)){
		int v=G[i];
		if(v==fa[u]) continue;
		fa[v]=u,dep[v]=dep[u]+1;
		dfs1(v);
		siz[u]+=siz[v];
		if(son[u]==-1||siz[v]>siz[son[u]]) son[u]=v;
	}
}
int top[MAXN],dfn[MAXN],rnk[MAXN],cnt;
inline void dfs2(int u,int t){
	top[u]=t;
	dfn[u]=++cnt;
	rnk[cnt]=u;
	if(son[u]==-1) return;
	dfs2(son[u],t);
	for(int i=G.head(u);i;i=G.nex(i)) if(G[i]!=son[u]&&G[i]!=fa[u]) dfs2(G[i],G[i]);
}
struct ST{
	int sum[MAXN<<2],lazy[MAXN<<2];
	inline void get(int rt){
		sum[rt]=(sum[rt<<1]+sum[rt<<1|1])%M;
	}
	inline void build(int rt,int l,int r){
		if(l==r){
			sum[rt]=arr[dfn[l]]%M;
			return;
		}
		int mid=(l+r)>>1;
		build(rt<<1,l,mid);
		build(rt<<1|1,mid+1,r);
		get(rt);
	}
	inline void push_down(int rt,int l,int r,int mid){
		lazy[rt<<1]=(lazy[rt<<1]+lazy[rt])%M,lazy[rt<<1|1]=(lazy[rt<<1|1]+lazy[rt])%M;
		sum[rt<<1]=(sum[rt<<1]+lazy[rt]*(mid-l+1))%M,sum[rt<<1|1]=(sum[rt<<1|1]+lazy[rt]*(r-mid))%M;
		lazy[rt]=0;
	}
	inline void updata(int rt,int l,int r,const int &L,const int &R,const int &val){
		if(L<=l&&r<=R){
			lazy[rt]=(lazy[rt]+val)%M;
			sum[rt]=(sum[rt]+val*(r-l+1))%M;
			return;
		}
		int mid=(l+r)>>1;
		if(lazy[rt]) push_down(rt,l,r,mid);
		if(L<=mid) updata(rt<<1,l,mid,L,R,val);
		if(R>mid) updata(rt<<1|1,mid+1,r,L,R,val);
		get(rt);
	}
	inline int query(int rt,int l,int r,const int &L,const int &R){
		if(L<=l&&r<=R) return sum[rt];
		int mid=(l+r)>>1;
		if(lazy[rt]) push_down(rt,l,r,mid);
		int ret=0;
		if(L<=mid) ret=(ret+query(rt<<1,l,mid,L,R))%M;
		if(R>mid) ret=(ret+query(rt<<1|1,mid+1,r,L,R))%M;
		return ret;
	}
};
ST t;
inline void change_road(int u,int v,int w){
	w%=M;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) Swap(u,v);
		t.updata(1,1,n,dfn[top[u]],dfn[u],w);
		u=fa[top[u]];
	}
	if(dep[u]>dep[v]) Swap(u,v);
	t.updata(1,1,n,dfn[u],dfn[v],w);
}
inline void change_tree(int u,int w){
	t.updata(1,1,n,dfn[u],dfn[u]+siz[u]-1,w);
}
inline int query_road(int u,int v){
	int ret=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]]) Swap(u,v);
		ret=(ret+t.query(1,1,n,dfn[top[u]],dfn[u]))%M;
		u=fa[top[u]];
	}
	if(dep[u]>dep[v]) Swap(u,v);
	return (ret+t.query(1,1,n,dfn[u],dfn[v]))%M;
}
inline int query_tree(int u){
	return t.query(1,1,n,dfn[u],dfn[u]+siz[u]-1)%M;
}
int main(){
	for(int i=1;i<=n;i++) arr[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G.add(u,v),G.add(v,u);
	}
	dfs1(root),dfs2(root,root);
	t.build(1,1,n);
	for(;m--;){
		int op=read();
		if(op==1){
			int x=read(),y=read(),z=read();
			change_road(x,y,z);
		}
		else if(op==2){
			int x=read(),y=read();
			printf("%d\n",query_road(x,y));
		}
		else if(op==3){
			int x=read(),z=read();
			change_tree(x,z);
		}
		else{
			int x=read();
			printf("%d\n",query_tree(x));
		}
	}
	return 0;
}
2022/8/19 18:50
加载中...