萌新求助点分树模板 T 飞
查看原帖
萌新求助点分树模板 T 飞
132533
FutaRimeWoawaSete楼主2022/2/13 16:38

RT。

#include "bits/stdc++.h"
using namespace std;
const int Len = 1e5 + 5 , Inf = 1e9;
int n,q,a[Len],head[Len],cnt,dfa[Len],dp[21][Len],dep[Len],mx[Len],siz[Len],S,rt,dis[Len],vis[Len];
int rtt[Len][2];
inline int read() {
    char ch = getchar();
    int x = 0, f = 1;
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while ('0' <= ch && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void write(int x) {
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}
struct Seg
{
	int tot,sum[Len * 60],lc[Len * 60],rc[Len * 60];
	inline void push_up(int p){sum[p] = sum[lc[p]] + sum[rc[p]];}
	void update(int &p,int l,int r,int idx,int w)
	{
		if(!p) p = ++ tot; 
		if(l == r){sum[p] += w;return;}
		int mid = (l + r) >> 1;
		if(idx <= mid) update(lc[p] , l , mid , idx , w);
		else update(rc[p] , mid + 1 , r , idx , w);
		push_up(p);
	} 
	int query(int p,int l,int r,int nl,int nr)
	{
		if(!p) return 0;
		if(nl <= l && nr >= r) return sum[p];
		int mid = (l + r) >> 1 , res = 0;
		if(nl <= mid) res += query(lc[p] , l , mid , nl , nr);
		if(nr > mid) res += query(rc[p] , mid + 1 , r , nl , nr);
		return res; 
	}
}S1;
struct node
{
	int next,to;
}edge[Len << 1];
inline void add(int from,int to)
{
	edge[++ cnt].to = to;
	edge[cnt].next = head[from];
	head[from] = cnt;
}
void dfs(int x,int f)
{
	dp[0][x] = f;
	dep[x] = dep[f] + 1;
	for(int i = 1 ; (1 << i) <= dep[x] ; i ++) dp[i][x] = dp[i - 1][dp[i - 1][x]];
	for(int e = head[x] ; e ; e = edge[e].next)
	{
		int to = edge[e].to;
		if(to == f) continue;
		dfs(to , x);
	}
}
inline int FLCA(int x,int y)
{
	if(dep[x] < dep[y]) swap(x , y);
	for(int i = 20 ; i >= 0 ; i --) if(dep[dp[i][x]] >= dep[y]) x = dp[i][x];
	if(x == y) return x;
	for(int i = 20 ; i >= 0 ; i --) if(dp[i][x] != dp[i][y]) x = dp[i][x] , y = dp[i][y];
	return dp[0][x];
}
inline int getdis(int x,int y){return dep[x] + dep[y] - dep[FLCA(x , y)] * 2;}
void resiz(int x,int f)
{
	siz[x] = 1;
	for(int e = head[x] ; e ; e = edge[e].next)
	{
		int to = edge[e].to;
		if(to == f || vis[to]) continue;
		resiz(to , x);
		siz[x] += siz[to];
	}
}
void getrt(int x,int f)
{
	mx[x] = 0 , siz[x] = 1;
	for(int e = head[x] ; e ; e = edge[e].next)
	{
		int to = edge[e].to;
		if(to == f || vis[to]) continue;
		getrt(to , x);
		siz[x] += siz[to];
		mx[x] = max(mx[x] , siz[to]);
	}
	mx[x] = max(mx[x] , S - siz[x]);
	if(mx[x] < mx[rt]) rt = x;
}
void Build(int x)
{
	vis[x] = 1;
	for(int e = head[x] ; e ; e = edge[e].next)
	{
		int to = edge[e].to;
		if(vis[to]) continue;
		S = siz[to] , mx[rt = 0] = Inf;
		getrt(to , 0);resiz(rt , 0);
		dfa[rt] = x , Build(rt);
	}
}
inline void upd(int x,int v)
{
	int now = x;
	while(now)
	{
		S1.update(rtt[now][0] , 0 , n - 1 , getdis(x , now) , v);
		if(dfa[now]) S1.update(rtt[now][1] , 0 , n - 1 , getdis(dfa[now] , x) , v);
		now = dfa[now];
	}
}
inline int qry(int x,int k)
{
	int now = x , pre = 0 , res = 0;
	while(now)
	{
		if(getdis(now , x) <= k)
		{
			int w1 = S1.query(rtt[now][0] , 0 , n - 1 , 0 , k - getdis(x , now)) , w2 = 0;
			if(pre) w2 = -S1.query(rtt[pre][1] , 0 , n - 1 , 0 , k - getdis(x , now));
			res += w1 + w2;
		}
		pre = now , now = dfa[now]; 
	}
	return res;
}
signed main()
{
	//freopen("P6329_1.in","r",stdin);
	//freopen("1.out","w",stdout);
	n = read() , q = read();
	for(int i = 1 ; i <= n ; i ++) a[i] = read();
	for(int i = 1 ; i < n ; i ++)
	{
		int x,y;x = read() , y = read();
		add(x , y) , add(y , x);
	}
	dfs(1 , 0);
	//resiz(1 , 0);
	mx[rt = 0] = Inf , S = n;
	getrt(1 , 0) , resiz(rt , 0) , Build(rt);
	//for(int i = 1 ; i <= n ; i ++) printf("!!!%d %d\n",i,dfa[i]);
	for(int i = 1 ; i <= n ; i ++) upd(i , a[i]);
	int lstans = 0;
	for(int i = 1 ; i <= q ; i ++) 
	{
		int opt,x,y;opt = read() , x = read() , y = read();
		x ^= lstans , y ^= lstans;
		if(opt == 0) write(lstans = qry(x , y)) , putchar('\n');
		else 
		{
			upd(x , y - a[x]);
			a[x] = y;
		}
	}  	
	return 0;
}
2022/2/13 16:38
加载中...