代码求调
查看原帖
代码求调
935908
zengziqvan楼主2024/5/18 11:31

样例没过

#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
//#define int long long
//#define double long double
#define FOR(i,l,r) for(int i=l;i<=r;++i)
#define ROF(i,r,l) for(int i=r;i>=l;--i)
#define mkp make_pair
#define fr first
#define se second
#define pb emplace_back
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
using namespace std;
const int N=1e5+10;
int n,m,rt,Mo,a[N],b[N],cnt,siz[N],son[N],fa[N],dep[N],idx[N],top[N];
vector<int>e[N];
void dfs1(int x,int fat) {
	fa[x]=fat;
	siz[x]=1;
	dep[x]=dep[fat]+1;
	for(int y:e[x]) {
		if(y==fat) continue;
		dfs1(y,x);
		siz[x]+=siz[y];
		if(siz[son[x]]<siz[y]) son[x]=y;
	}
}
void dfs2(int x,int tp) {
	idx[x]=++cnt;
	top[x]=tp;
	if(!son[x]) return ;
	dfs2(son[x],tp);
	for(int y:e[x]) {
		if(y==fa[x]||y==son[x]) continue;
		dfs2(y,y);
	}
}
struct SegmentTree {
	int l,r,sum,tag,en;
} t[N<<2];
void push_up(int p) {
	t[p].sum=(t[p<<1].sum+t[p<<1|1].sum)%Mo;
}
void Build(int p,int l,int r) {
	t[p].l=l,t[p].r=r,t[p].en=r-l+1;
	if(l==r) return (void)(t[p].sum=a[idx[l]]);
	int mid=l+r>>1;
	Build(p<<1,l,mid);
	Build(p<<1|1,mid+1,r);
	push_up(p);
}
void push_down(int p) {
	if(!t[p].tag) return ;
	t[p<<1].sum=(t[p<<1].sum+t[p<<1].en*t[p].tag%Mo)%Mo;
	t[p<<1|1].sum=(t[p<<1|1].sum+t[p<<1|1].en*t[p].tag%Mo)%Mo;
	t[p<<1].tag+=t[p].tag;
	t[p<<1].tag%=Mo;
	t[p<<1|1].tag+=t[p].tag;
	t[p<<1|1].tag%=Mo;
	t[p].tag=0;
}
void change(int p,int l,int r,int x) {
	if(l<=t[p].l&&t[p].r<=r) return (void)(t[p].tag=(t[p].tag+x)%Mo,t[p].sum=(t[p].sum+t[p].en*x%Mo)%Mo);
	push_down(p);
	int mid=t[p].l+t[p].r>>1;
	if(l<=mid) change(p<<1,l,r,x);
	if(r>mid) change(p<<1|1,l,r,x);
	push_up(p);
}
int ask(int p,int l,int r) {
	if(l<=t[p].l&&t[p].r<=r) return t[p].sum;
	int mid=t[p].l+t[p].r>>1,val;
	push_down(p);
	if(l<=mid) val=(val+ask(p<<1,l,r))%Mo;
	if(r>mid) val=(val+ask(p<<1|1,l,r))%Mo;
	return val;
}
int Treeask(int x,int y) {
	int ans=0;
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans=(ans+ask(1,idx[top[x]],top[x]))%Mo;
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	ans=(ans+ask(1,idx[x],idx[y]))%Mo;
	return ans;
}
void Treeupdate(int x,int y,int z) {
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		change(1,idx[top[x]],idx[x],z);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	change(1,idx[x],idx[y],z);
}
main() {
	cin>>n>>m>>rt>>Mo;
	FOR(i,1,n) scanf("%d",&a[i]);
	FOR(i,1,n-1) {
		int u,v;
		scanf("%d%d",&u,&v);
		e[u].pb(v);
		e[v].pb(u);
	}
	dfs1(rt,0),dfs2(rt,rt);
	Build(1,1,n);
	while(m--) {
		int op,x,y,z;
		scanf("%d",&op);
		if(op==1) {
			scanf("%d%d%d",&x,&y,&z);
			Treeupdate(x,y,z%Mo);
		}
		if(op==2) {
			scanf("%d%d",&x,&y);
			printf("%d\n",Treeask(x,y));
		}
		if(op==3) {
			scanf("%d%d",&x,&z);
			change(1,idx[x],idx[x]+siz[x]-1,z%Mo);
		}
		if(op==4) {
			scanf("%d",&x);
			printf("%d\n",ask(1,idx[x],idx[x]+siz[x]-1));
		}
	}
	return 0;
}
2024/5/18 11:31
加载中...