蒟蒻刚学树剖1ms,全WA求条
查看原帖
蒟蒻刚学树剖1ms,全WA求条
974911
rzt123楼主2024/6/15 16:47

rt

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n;
vector<int> g[N];
int a[N];
int dfn[N];
int fa[N];
int siz[N];
int son[N];
int dep[N];
int top[N];
int bot[N];
int rnk[N];
void dfs1(int o)
{
	siz[o]=1;
	son[o]=-1;
	for(int e:g[o])
	{
		if(e!=fa[o])
		{
			dep[e]=dep[o]+1;
			fa[e]=o;
			siz[e]=1;
			dfs1(e);
			siz[o]+=siz[e];
			if(son[o]==-1||siz[son[o]]<siz[e])son[o]=e;
		}
	}
}
int cnt;
void dfs2(int tot,int o)
{
	dfn[o]=++cnt;
	rnk[cnt]=o;
	top[o]=tot;
	bot[o]=cnt;
	if(son[o]!=-1)
	{
		dfs2(tot,son[o]);
		bot[o]=bot[son[o]];
	}
	for(int e:g[o])
	{
		if(e!=son[o]&&e!=fa[o])
		{
			dfs2(e,e);
			bot[o]=bot[e];
		}
	}
}
struct Node
{
	int l,r,v,lazy;
};
struct Tree 
{
	Node tr[N<<2];
	#define lson (rt<<1)
	#define rson (rt<<1|1)
	#define mid ((l+r)>>1)
	void pushup(int rt)
	{
		tr[rt].v=tr[lson].v+tr[rson].v; 
	}
	void pushdown(int rt)
	{
		int k=tr[rt].lazy;
		tr[lson].v+=(tr[lson].r-tr[lson].l+1)*k;
		tr[lson].lazy+=k;
		tr[rson].v+=(tr[rson].r-tr[rson].l+1)*k;
		tr[rson].lazy+=k;
		tr[rt].lazy=0;
	}
	void build(int rt,int l,int r)
	{
		tr[rt]={l,r};
		if(l==r)
		{
			tr[rt].v=a[rnk[l]];
			return ;
		}
		build(lson,l,mid);
		build(rson,mid+1,r);
		pushup(rt); 
	}
	int query(int rt,int st,int ed)
	{
		int l=tr[rt].l,r=tr[rt].r;
		if(st<=l&&r<=ed)
		{
			return tr[rt].v;
		}
		pushdown(rt);
		if(ed<=mid)
		{
			return query(lson,st,ed);
		} 
		if(mid<st)
		{
			return query(rson,st,ed);
		}
		int L=query(lson,st,ed);
		int R=query(rson,st,ed);
		return L+R;
	} 
	void update(int rt,int st,int ed,int k)
	{
		int l=tr[rt].l,r=tr[rt].r;
		if(st<=l&&r<=ed)
		{
			tr[rt].v+=(r-l+1)*k;
			tr[rt].lazy+=k;
			return ;
		}
		pushdown(rt); 
		if(st<=mid)
		{
			update(lson,st,ed,k);
		}
		if(mid<ed)
		{
			update(rson,st,ed,k);
		}
		pushup(rt);
	}
	#undef lson
	#undef rson
	#undef mid
}tree;
void add_subtree(int x,int k)
{
	tree.update(1,dfn[x],bot[x],k);
}
void add_point(int x,int k)
{
	tree.update(1,dfn[x],dfn[x],k);
}
int query_path(int x)
{
	int y=1;
	int res=0;	
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]])
		{
			swap(x,y);
		}
		res+=tree.query(1,dfn[top[x]],dfn[x]);
		x=fa[top[x]];
	}
	if(dfn[x]<dfn[y])
	{
		swap(x,y);
	}
	res+=tree.query(1,y,x);
	return res;
}
int m;
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dep[1]=1;
	dfs1(1);
	dfs2(1,1);
	tree.build(1,1,n);
	while(m--)
	{
		int op,x;
		cin>>op>>x;
		if(op==1)
		{
			int k;
			cin>>k;
			add_point(x,k);
		}
		else if(op==2)
		{
			int k;
			cin>>k;
			add_subtree(x,k); 
		}
		else
		{
			cout<<query_path(x)<<endl;;
		}
//		for(int i=1;i<=n;i++)
//		{
//			cout<<tree.query(1,dfn[i],dfn[i])<<" ";
//		 } 
//		 cout<<endl;
	}
	return 0;
}

2024/6/15 16:47
加载中...