RE 求助
查看原帖
RE 求助
420129
Nt_Tsumiki楼主2023/3/23 10:18
#include <iostream>
#include <cstdio>

namespace Segment_tree {
	struct Nade {
		int val,l,r;
	}t[3][2000001];
	
	int tot[3],root[3][1000001];
	
	void add(int &x,int l,int r,int pos,int k,int p) {
		if (!x) x=++tot[p];
		if (l>=r) {
			t[p][x].val+=k;
			return;
		} int mid=(l+r>>1);
		if (pos<=mid) add(t[p][x].l,l,mid,pos,k,p);
		if (pos>mid) add(t[p][x].r,mid+1,r,pos,k,p);
		t[p][x].val=t[p][t[p][x].l].val+t[p][t[p][x].r].val;
	}
	
	int ask(int x,int l,int r,int L,int R,int p) {
		if (!x) return 0;
		if (L<=l and r<=R) return t[p][x].val;
		int mid=(l+r>>1),res=0;
		if (L<=mid) res+=ask(t[p][x].l,l,mid,L,R,p);
		if (R>mid) res+=ask(t[p][x].r,mid+1,r,L,R,p);
		return res;
	}
}
using namespace Segment_tree; 
using namespace std;
int n,m,cnt,rt,las;
int a[1000001],head[1000001],siz[1000001],msz[1000001],vis[1000001],ffa[1000001];

struct Node { int to,nxt; }e[2000001];

void add(int x,int y) { e[++cnt]=(Node){y,head[x]},head[x]=cnt; }

void find(int x,int f,int S) {
	siz[x]=1,msz[x]=0;
	for (int i=head[x];i;i=e[i].nxt) {
		int y=e[i].to;
		if (y==f or vis[y]) continue;
		find(y,x,S);
		siz[x]+=siz[y];
		msz[x]=max(msz[x],siz[y]);
	}
	msz[x]=max(msz[x],S-siz[x]);
	if (msz[x]<msz[rt]) rt=x;
}

void dfs(int x,int S) {
	vis[x]=1;
	for (int i=head[x];i;i=e[i].nxt) {
		int y=e[i].to;
		if (vis[y]) continue;
		int sz=siz[y]<siz[x]?siz[y]:S-siz[x],rt=0;
		find(y,0,sz);
		ffa[rt]=x;
		dfs(rt,sz);
	}
}

int son[1000001],fa[1000001],dep[1000001],top[1000001];

void dfs1(int x,int f) {
	fa[x]=f,siz[x]=1,dep[x]=dep[f]+1;
	for (int i=head[x];i;i=e[i].nxt) {
		int y=e[i].to;
		if (y==f) continue;
		dfs1(y,x);
		siz[x]+=siz[y];
		if (siz[y]>siz[son[x]]) son[x]=y;
	}
}

void dfs2(int x,int topp) {
	top[x]=topp;
	if (son[x]) dfs2(son[x],topp);
	for (int i=head[x];i;i=e[i].nxt) {
		int y=e[i].to;
		if (y==fa[x] or y==son[x]) continue;
		dfs2(y,y);
	}
}

int LCA(int x,int y) {
	while (top[x]!=top[y]) {
		if (dep[top[x]]<dep[top[y]]) swap(x,y);
		x=fa[top[x]];
	}
	if (dep[x]>dep[y]) swap(x,y);
	return x;
}

void upd(int x,int val) {
	int ff=x;
	while (ff) {
		add(root[1][ff],0,n-1,dep[ff]+dep[x]-2*dep[LCA(ff,x)],val,1);
		if (ffa[ff]) add(root[2][ff],0,n-1,dep[ffa[ff]]+dep[x]-2*dep[LCA(ffa[ff],x)],val,2);
		ff=ffa[ff];
	}
}

int aask(int x,int k) {
	int ff=x,fs=0,res=0;
	while (ff) {
		int d=dep[ff]+dep[x]-2*dep[LCA(ff,x)];
		if (d>k) {
			fs=ff,ff=ffa[ff];
			continue;
		}
		res+=ask(root[1][ff],0,n-1,0,k-d,1);
		if (ffa[ff]) res-=ask(root[2][fs],0,n-1,0,k-d,2);
		fs=ff,ff=ffa[ff];
	}
	return res;
}

int main() {
	freopen("P6329_1.in","r",stdin);
	freopen("1.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++) scanf("%d",a+i);
	for (int i=1,x,y;i<n;i++) {
		scanf("%d%d",&x,&y);
		add(x,y),add(y,x);
	}
	msz[0]=1e9;
	find(1,0,n);
	dfs(rt,n);
	dfs1(1,0);
	dfs2(1,1);
	
	for (int i=1;i<=n;i++) upd(i,a[i]); 
	while (m--) {
		int opt,x,y;
		scanf("%d%d%d",&opt,&x,&y);
		x^=las,y^=las;
		if (!opt) printf("%d\n",las=aask(x,y));
		else {
			upd(x,y-a[x]);
			a[x]=y;
		}
	}
	return 0;
}
/*
8 1
1 10 100 1000 10000 100000 1000000 10000000
1 2 1 3 2 4 2 5 3 6 3 7 3 8
0 3 1
*/
2023/3/23 10:18
加载中...