10pts求调
查看原帖
10pts求调
1399834
chengzihan_201200726楼主2025/8/4 15:26
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define mid ((l+r)>>1)
#define ls (k<<1)
#define rs (k<<1|1)
int read(){
  	ll x=0,f=1;char c=getchar();
  	while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
  	while(isdigit(c)){x=x*10+c-'0';c=getchar();}
  	return x*f;
}
const int N=1e5+10;
int head[N<<2],cnt;
int siz[N<<2],dis[N],pos[N<<2],tot,top[N<<2],fa[N<<2],her[N<<2],dfn[N<<2],laz[N<<2],tr[N<<2];
int n,m,r,p,a[N];
//---------------------------------------------------------定义变量
struct edge
{
	int v,nxt;
}e[N<<2];
void add(int u,int v)
{
	e[++cnt].v=v;
	e[cnt].nxt=head[u];
	head[u]=cnt;
}
//----------------------------------------------------------链式前向星建图
void add1(int k,int l,int r,int v){
	laz[k]+=v;tr[k]+=(r-l+1)*v;
	return; 
}
void pushup(int k,int l,int r){
	tr[k]=tr[ls]+tr[rs]+(r-l+1)*laz[k];
}
void build(int k,int l,int r){
	if(l==r){
		tr[k]=a[dfn[l]];
		return;
	}
	build(ls,l,mid);
	build(rs,mid+1,r);
	pushup(k,l,r);
	return;
}
void change(int k,int l,int r,int x,int y,ll v){
	//assert(x<=y);
	if(x<=l&&r<=y){
		add1(k,l,r,v);
		return;
	}
	if(x<=mid)change(ls,l,mid,x,y,v);
	if(y>mid)change(rs,mid+1,r,x,y,v);
	pushup(k,l,r);
	return;
}
int ask(int k,int l,int r,int x,int y){
	//assert(x<=y);
	if(x<=l&&r<=y)return tr[k];
    ll res=(min(y,r)-max(x,l)+1)*laz[k];
	if(x<=mid)res+=ask(ls,l,mid,x,y)%p;
	if(y>mid)res+=ask(rs,mid+1,r,x,y)%p;
	return res%p;
}
//---------------------------------------------线段树
void dfs1(int x,int f){
	fa[x]=f,dis[x]=dis[f]+1,siz[x]=1;
	for(int i=head[x];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==f)continue;
		dfs1(v,x);
		siz[x]+=siz[v];
		if(siz[v]>=siz[her[x]])her[x]=v;
	}
}
void dfs2(int x,int tp){
	top[x]=tp,dfn[++tot]=x,pos[x]=tot;
	if(her[x])dfs2(her[x],tp);
	for(int i=head[x];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fa[x]||v==her[x])continue;
		dfs2(v,v);
	}
}
void upd(int x,int y,ll v) {
	//printf("upd: x=%lld y=%lld",x,y);
	while(top[x]!=top[y]) {
		if(dis[top[x]]<dis[top[y]]) swap(x,y);
		change(1,1,n,pos[top[x]],pos[x],v);
		//printf("  jump: x=%lld (%lld %lld)\n",x,pos[top[x]],pos[x]);
		x=fa[top[x]];
	}
	if(dis[x]<dis[y]) swap(x,y);
	//printf("  jump: %lld %lld\n",pos[y],pos[x]);
	change(1,1,n,pos[y],pos[x],v);
}
int query(int x,int y) {
	int ans=0;
	while(top[x]!=top[y]) {
		if(dis[top[x]]<dis[top[y]]) swap(x,y);
		ans+=ask(1,1,n,pos[top[x]],pos[x])%p;
		x=fa[top[x]];
	}
	if(dis[x]<dis[y]) swap(x,y);
	ans+=ask(1,1,n,pos[y],pos[x])%p;
	return ans%p;
}
//-------------------------------------------------以上为树链剖分
signed main()
{
	//freopen("a.in","r",stdin);
	//freopen("a.out","w",stdout);
	n=read(),m=read(),r=read(),p=read();
	for(int i=1;i<=n;i++)a[i]=read();
	
	for(int i=1;i<=n-1;i++){
		int x,y;
		x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	dfs1(r,0);
	dfs2(r,r);
	build(1,1,n);
	for(int i=1;i<=m;i++){
		int opt;
		//cout<<"i="<<i<<endl;
		opt=read();
		if(opt==1){
			int x,y,z;
			x=read(),y=read(),z=read();
			upd(x,y,z);

		}
		else if(opt==2){
			int x,y;
			x=read(),y=read();
			printf("%lld\n",query(x,y)%p);
		}
		else if(opt==3){
			int x,y;
			x=read(),y=read();
			for(int i=pos[x];i<=pos[x]+siz[x];i++){
				a[i]+=y%p;
				//printf("a=%d\n",a[i]);
			}
		}
		else {
			int res=0;
			int x;
			x=read();
			for(int i=pos[x];i<=pos[x]+siz[x];i++){
				res+=a[i]%p;
			}
			printf("%lld\n",res%p);
		}
	}
	return 0;
}

1~7wa 8~10tle 11AC

2025/8/4 15:26
加载中...