RE求调
查看原帖
RE求调
1151738
xyztapeplayer楼主2024/4/26 17:18
#include<bits/stdc++.h>
using namespace std;
struct node{
	int l,r,sum,lz;
};
node tree[400005];
vector<int> a[400005];
int in[400005],deep[400005],siz[400005],fa[400005],son[400005],rnk[400005],top[400005],dfn[400005],cnt,n,m,mod,root;
void build(long long p,long long l,long long r){
	tree[p].l=l,tree[p].r=r;
	if(l==r){tree[p].sum=rnk[l];return;}
	long long mid=(l+r)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	tree[p].sum=(tree[p*2].sum+tree[p*2+1].sum)%mod;
}

void push_down(int p){
	if(!tree[p].lz) return; 
	tree[p*2].lz+=tree[p].lz;
	tree[p*2+1].lz+=tree[p].lz;
	int mid=(tree[p].l+tree[p].r)/2;
	tree[p*2].sum+=tree[p].lz*(mid-tree[p*2].l+1);
	tree[p*2+1].sum+=tree[p].lz*(tree[p*2+1].r-mid);
	tree[p].lz=0;
}
void add(int p,int l,int r,int k){
//	cout<<p<<" "<<l<<" "<<r<<endl;
	if(tree[p].l>=l&&tree[p].r<=r){
		tree[p].sum+=k*(tree[p].r-tree[p].l+1);
		tree[p].lz+=k;
		return;
	}
	push_down(p);
	int mid=(tree[p].l+tree[p].r)/2;
    if(mid>=l) add(p*2,l,r,k);
    if(mid<r) add(p*2+1,l,r,k);
    tree[p].sum=(tree[p*2].sum+tree[p*2+1].sum)%mod;
    //cout<<tree[p].l<<" "<<tree[p].r<<" "<<tree[p].sum<<endl;
}
int search(int p,int l,int r){
	if(tree[p].l>=l&&tree[p].r<=r){
		return tree[p].sum;
	}
	if(tree[p].r<l||tree[p].l>r) return 0;
	push_down(p);
	int s=0;
	int mid=(tree[p].l+tree[p].r)/2;
    if(mid>=l) s+=search(p*2,l,r);
    s%=mod;
    if(mid<r) s+=search(p*2+1,l,r);
    s%=mod;
    //cout<<tree[p].l<<" "<<tree[p].r<<" "<<s<<endl;
    return s;
}
void dfs1(int u,int f){
	siz[u]=1;
//	cout<<u<<endl;
	for(int i=0;i<a[u].size();i++){
		if(a[u][i]==f) continue;
//		cout<<i<<":"<<a[u][i]<<endl;
		fa[a[u][i]]=u;
		deep[a[u][i]]=deep[u]+1;
		dfs1(a[u][i],u);
		siz[u]+=siz[a[u][i]];
		if(siz[a[u][i]]>siz[son[u]]) son[u]=a[u][i];
	}
}
void dfs2(int u,int tp){
	dfn[u]=++cnt;
	top[u]=tp;
	rnk[cnt]=in[u];
	if(!son[u]) return;
	dfs2(son[u],tp);
	for(int i=0;i<a[u].size();i++){
		if(a[u][i]!=fa[u]&&a[u][i]!=son[u]) 
			dfs2(a[u][i],a[u][i]);
	}
}
void addtree(int x,int y,int c){
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		add(1,dfn[top[x]],dfn[x],c);
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	add(1,dfn[x],dfn[y],c);
}
int searchtree(int x,int y){
	int ans=0;
	while(top[x]!=top[y]){
		if(deep[top[x]]<deep[top[y]]) swap(x,y);
		ans+=search(1,dfn[top[x]],dfn[x]);
		ans%=mod;
		x=fa[top[x]];
	}
	if(deep[x]>deep[y]) swap(x,y);
	ans+=search(1,dfn[x],dfn[y]);
	ans%=mod;
	return ans;
} 
int main(){
	cin>>n>>m>>root>>mod;
	for(int i=1;i<=n;i++) cin>>in[i];
	for(int i=1;i<n;i++){
		int u,v;
		cin>>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);
	}
// 	cout<<"图:"<<endl;
// 	for(int i=1;i<=n;i++){
// 		cout<<i<<": ";
// 		for(int j=0;j<a[i].size();j++) cout<<a[i][j]<<" ";
// 		cout<<endl;
// 	}
//	cout<<"dfs1:"<<endl;
	fa[root]=root;
	dfs1(root,root);
	dfs2(root,root);
// 	build(1,1,n);
// 	cout<<"dfs序: ";
// 	for(int i=1;i<=n;i++) cout<<dfn[i]<<" ";
// 	cout<<endl<<"子树大小: ";
// 	for(int i=1;i<=n;i++) cout<<siz[i]<<" ";
// 	cout<<endl<<"重儿子: ";
// 	for(int i=1;i<=n;i++) cout<<son[i]<<" ";
// 	cout<<endl<<"深度: ";
// 	for(int i=1;i<=n;i++) cout<<deep[i]<<" ";
// 	cout<<endl<<"父亲: ";
// 	for(int i=1;i<=n;i++) cout<<fa[i]<<" ";
// 	cout<<endl<<"当前DFS序对应的值: ";
// 	for(int i=1;i<=n;i++) cout<<rnk[i]<<" ";
// 	cout<<endl;
	while(m--){
		int op;
		cin>>op;
		if(op==1){
			int x,y,z;
			cin>>x>>y>>z;
			addtree(x,y,z);
		}
		if(op==2){
			int x,y;
			cin>>x>>y;
			cout<<searchtree(x,y)<<endl;
		}
		if(op==3){
			int x,y;
			cin>>x>>y;
			add(1,dfn[x],dfn[x]+siz[x]-1,y%mod);
		}
		if(op==4){
			int x;
			cin>>x;
			cout<<search(1,dfn[x],dfn[x]+siz[x]-1)<<endl;
		}
	}
	return 0;
}
2024/4/26 17:18
加载中...