蒟蒻刚学树上差分,95分,求调!!
查看原帖
蒟蒻刚学树上差分,95分,求调!!
342626
Blue_Fire楼主2024/7/27 12:03
#include<iostream>
#include<cstdio>
#include<vector> 
using namespace std;
const int maxn = 3e5+10;
struct node{
	long long k;
	int id;
};
int n,q;
vector<int> g[maxn];
vector<node> v[maxn];
long long ans[maxn];
long long dep[maxn],sz[maxn];
long long c[maxn];//树状数组

int lowbit(long long x){
	return x&-x;
}

void add(int now,long long x){
	while(now <= n){
		c[now] += x;
		now += lowbit(now);
	}
}

long long query(int now){
	long long res = 0;
	while(now){
		res += c[now];
		now -= lowbit(now);
	}
	return res;
}

void dfs2(int u,int fa){
	for(auto x : v[u]){
		ans[x.id] -= (query(dep[u]+x.k)-query(dep[u]));
	}
	add(dep[u],sz[u]-1);
	for(auto x : g[u]){
		if(x == fa) continue;
		dfs2(x,u);
	}
	for(auto x : v[u]){
		ans[x.id] += (query(dep[u]+x.k)-query(dep[u]));
	}
}

void dfs1(int u,int fa){
	dep[u] = dep[fa]+1;
	sz[u] += 1;
	for(auto x : g[u]){
		if(x == fa) continue;
		dfs1(x,u);
		sz[u] += sz[x];
	}
}

int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<n;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1,0);
	for(int i=1;i<=q;i++){
		int p;
		long long k;
		scanf("%d%lld",&p,&k);
		v[p].push_back((node){k,i});
		ans[i] += min(dep[p]-1,k)*(sz[p]-1);
	}
	dfs2(1,0);
	for(int i=1;i<=q;i++){
		printf("%lld\n",ans[i]);
	}
	return 0;
}
2024/7/27 12:03
加载中...