树链剖分板子求调(玄关
查看原帖
树链剖分板子求调(玄关
1423269
ini_____楼主2025/1/23 16:01

rt,998244353年前写的树链剖分板子,不知道错哪了,能过样例,但是只有20pts

#include<bits/stdc++.h>
#define ll __int128
using namespace std;
const int N=100010;
int n,m,s;
ll p;
int h[N],e[N*2],ne[N*2],idx;
void add_edge(int a,int b){
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int w[N],id[N];
ll seq[N],cnt;
int dep[N],sz[N],top[N],fa[N],wson[N];
ll sum[N*4],lazy[N*4]; 
inline ll read(){
	int x=0,f=1;
	char c=getchar();
	while(c<'0' or c>'9'){
		if(c=='-')f=-1;
		c=getchar();
	}
	while('0'<=c and c<='9'){
		x=(x<<1)+(x<<3)+c-48;
		c=getchar(); 
	}
	return x;
}
void dfs1(int u,int f,int d){
	dep[u]=d,fa[u]=f,sz[u]=1;
	for(int i=h[u];~i;i=ne[i]){
		int v=e[i];
		if(v==f)continue;
		dfs1(v,u,d+1);
		sz[u]+=sz[v];
		if(sz[v]>sz[wson[u]])wson[u]=v;
	}
}
void dfs2(int u,int t){
	id[u]=++cnt;
	seq[cnt]=w[u],top[u]=t;
	if(!wson[u])return;
	dfs2(wson[u],t);
	for(int i=h[u];~i;i=ne[i]){
		int v=e[i];
		if(v==fa[u] or v==wson[u])continue;
		dfs2(v,v);
	}
}
void build(int l,int r,int index){
	lazy[index]=0;
	if(l==r){sum[index]=seq[l];return;}
	int mid=(l+r)>>1;
	build(l,mid,index*2);
	build(mid+1,r,index*2+1);
	sum[index]=sum[index*2]+sum[index*2+1];
	return;
}
void change(int l,int r,int x,int y,int index,ll v){
	if(x<=l and r<=y){
		lazy[index]+=v;
		sum[index]+=v*(r-l+1);
		return;
	}
	int mid=(l+r)>>1;
	if(lazy[index]){
		change(l,mid,1,n,index*2,lazy[index]);
		change(mid+1,r,1,n,index*2+1,lazy[index]);
		lazy[index]=0;
	}
	if(x<=mid)change(l,mid,x,y,index*2,v);
	if(mid+1<=y)change(mid+1,r,x,y,index*2+1,v);
}
ll query(int l,int r,int x,int y,int index){
	if(x<=l and r<=y)return sum[index];
	int mid=(l+r)>>1;
	if(lazy[index]){
		change(l,mid,1,n,index*2,lazy[index]);
		change(mid+1,r,1,n,index*2+1,lazy[index]);
		lazy[index]=0;
	}
	ll res=0;
	if(x<=mid)res+=query(l,mid,x,y,index*2);
	if(mid+1<=y)res+=query(mid+1,r,x,y,index*2+1);
	return res;
}
void update_pat(int u,int v,int k){
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		change(1,n,/*l*/id[top[u]],/*r*/id[u],1,k);
		u=fa[top[u]];
	}
	if(dep[u]<dep[u])swap(u,v);
	change(1,n,id[v],id[u],1,k);
}
void update_tre(int u,int k){change(1,n,id[u],id[u]+sz[u]-1,1,k);}
ll query_pat(int u,int v){
	ll res=0;
	while(top[u]!=top[v]){
		if(dep[top[u]]<dep[top[v]])swap(u,v);
		res+=query(1,n,/*l*/id[top[u]],/*r*/id[u],1);
		u=fa[top[u]];
	}
	if(dep[u]<dep[u])swap(u,v);
	res+=query(1,n,id[v],id[u],1);
	return res;
}
ll query_tre(int u){return query(1,n,id[u],id[u]+sz[u]-1,1);}
int main(){
	memset(h,-1,sizeof h);
	n=read(),m=read(),s=read(),p=read();
	for(int i=1;i<=n;i++)w[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs1(s,-1,1);
	dfs2(s,s);
	build(1,n,1); 
	while(m--){
		int op=read();
		int u,v,k;
		if(op==1){
			u=read(),v=read(),k=read();
			update_pat(u,v,k);
		}
		if(op==3){
			u=read(),k=read();
			update_tre(u,k);
		}
		if(op==2){
			u=read(),v=read();
			cout<<(long long)(query_pat(u,v)%p)<<endl;
		}
		if(op==4){
			u=read();
			cout<<(long long)(query_tre(u)%p)<<endl; 
		}
	}
}
/*
8 10 2 448348
458 718 447 857 633 264 238 944 
1 2
2 3
3 4
6 2
1 5
5 7
8 6
3 7 611
4 6
3 1 267
3 2 111
1 6 3 153
3 7 673
4 8
2 6 1
4 7
3 4 228


1208
1055
2346
1900
输出错误的样例
*/
2025/1/23 16:01
加载中...