除 #3Wa外全部 RE,悬关求调
查看原帖
除 #3Wa外全部 RE,悬关求调
525375
Richard_Whr楼主2023/11/30 22:54
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=N*2;
int h[N],e[M],ne[M],w[M],idx;
bool st[N];
int val[N];
vector<int> son[N];
struct Father
{
	int u,k;
	int dist;
};
vector<Father> f[N];
struct tree
{
	int n;
	vector<int> tr;
	inline void resize(int _n)
	{
		n=_n+1;
		tr.resize(_n+3);
	}
	inline int lowbit(int x)
	{
		return x&-x;
	}
	inline void add(int x,int c)
	{
		for(int i=x;i<=n;i+=lowbit(i)) tr[i]+=c; 
	}
	inline int sum(int x)
	{
		if(x>n) x=n;
		int res=0;
		for(int i=x;i;i-=lowbit(i)) res+=tr[i];
		return res;
	}
}root[N];
int n,m,rt;

void add(int a,int b)
{
	e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

int get_size(int u,int fa)
{
	if(st[u]) return 0;
	int res=1;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa) continue;
		res+=get_size(j,u);
	}
	return res;
}

int get_wc(int u,int fa,int tot,int &wc)
{
	if(st[u]) return 0;
	int sum=1,ms=0;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa) continue;
		int t=get_wc(j,u,tot,wc);
		sum+=t;
		ms=max(ms,t);
	}
	ms=max(ms,tot-sum);
	if(ms<=tot/2) wc=u;
	return sum;
}

void get_dist(int u,int fa,int dist,int wc,int k)
{	
	if(st[u]) return;
	f[u].push_back({wc,k,dist});
	root[wc].add(dist,val[u]);
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(j==fa) continue;
		get_dist(j,u,dist+1,wc,k);
	}
}

void build(int u,int fa)
{
	if(st[u]) return;
	int sz=get_size(u,-1);
	get_wc(u,-1,sz,u);	
	
	st[u]=true;
	root[u].resize(sz);
	
	if(fa) son[fa].push_back(u);
	else rt=u;
	
	int k=0;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		if(st[j]) continue;
		get_dist(j,u,1,u,k);
		k++;
	}
	
	for(int i=h[u];~i;i=ne[i]) build(e[i],u);
} 

void modify(int u,int y)
{
	for(auto t:f[u])
	{
		int id=t.u;
		root[id].add(t.dist,-val[u]);
		root[id].add(t.dist,y);
	}
	val[u]=y;
}

int query(int u,int k)
{
	int res=0;
	for(auto &t:f[u])
	{
		int id=t.u,sid=son[id][t.k];
		if(!sid) continue;
		if(t.dist>k) continue;
		res+=val[id];
		res+=root[id].sum(k-t.dist);
		res-=root[sid].sum(k-t.dist);
	}
	res+=val[u];
	res+=root[u].sum(k);
	
	return res;
}

int main()
{
	memset(h,-1,sizeof h);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>val[i];
	
	for(int i=1,a,b;i<n;i++) cin>>a>>b,add(a,b),add(b,a);
	
	build(1,0);
	
	int res=0;
	while(m--)
	{
		int op,x,y;
		cin>>op>>x>>y;
		x=x^res,y=y^res;
		if(op==0)
		{
			res=query(x,y);
			cout<<res<<"\n";
		}
		else 
		{
			modify(x,y);
		}
	}
	
	return 0;
}
2023/11/30 22:54
加载中...