线段树合并 WA 50 pts 求调
查看原帖
线段树合并 WA 50 pts 求调
754310
Pepsee楼主2023/11/25 14:23

没有可持久化,是离线的,但感觉没有问题 qwq

#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+5;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
int n,m;
struct segt{
	int ls,rs,val;
}tr[8000005];
struct que {int id,x;};
vector<que> q[maxn];
struct node{
	int nex,to;
}edge[maxn<<1];
int head[maxn],cnt,tot;
int root[maxn],dep[maxn],f[maxn][22];
int ans[maxn],siz[maxn];
void add(int x,int y)
{
	edge[++tot].nex = head[x];
	edge[tot].to = y;
	head[x] = tot;
}
//-----------以下为线段树-----------
void pushup(int rt){
	tr[rt].val = tr[tr[rt].ls].val+tr[tr[rt].rs].val;
}
int merge(int x,int y,int l,int r)
{
	if (!x) return y;
	if (!y) return x;
	if (l == r){
		tr[x].val = tr[x].val+tr[y].val;
		return x;		
	}
	int mid = (l+r) >> 1;
	tr[x].ls = merge(tr[x].ls,tr[y].ls,l,mid);
	tr[x].rs = merge(tr[x].rs,tr[y].rs,mid+1,r);
	pushup(x);
	return x;
}
int add(int rt,int l,int r,int x,int a)
{
	if (!rt) rt = ++cnt;
	if (l == r){
		tr[rt].val += a;
		return rt;
	}
	int mid = (l+r) >> 1;
	if (x <= mid) tr[rt].ls = add(tr[rt].ls,l,mid,x,a);
	else tr[rt].rs = add(tr[rt].rs,mid+1,r,x,a);
	pushup(rt);
	return rt;
}
int query(int rt,int l,int r,int x,int y)
{
	int res = 0;
	if (l >= x && r <= y)
		return tr[rt].val;
	int mid = (l+r) >> 1;
	if (x <= mid && tr[rt].ls) res += query(tr[rt].ls,l,mid,x,y);
	if (y > mid && tr[rt].rs) res += query(tr[rt].rs,mid+1,r,x,y);
	return res;
}
//-----------以上为线段树----------- 
void dfs(int x,int fa)
{
	dep[x] = dep[fa]+1; f[x][0] = fa;
	siz[x] = 1;	
	for (int i = 1; i <= 20; i++)
		f[x][i] = f[f[x][i-1]][i-1];
	for (int i = head[x]; i; i = edge[i].nex)
	{
		int v = edge[i].to;
		if (v == fa) continue;
		dfs(v,x);
		siz[x] += siz[v];
	}
	root[x] = add(root[x],1,3e5,dep[x],siz[x]-1);
}
int find(int p,int k)
{
	int st = p;
	for (int i = 20; ~i; i--)
		if (dep[p]-dep[f[p][i]] <= k)
			k -= (dep[f[p][i]]-dep[p]),p = f[p][i];
	p = (p<=0)?1:p;
	return dep[st]-dep[p];
}
void solve(int x)
{
	for (int i = head[x]; i; i = edge[i].nex)
	{
		int v = edge[i].to;
		if (v == f[x][0]) continue;
		solve(v);
		root[x] = merge(root[x],root[v],1,3e5);
	}
	for (int i = 0; i < q[x].size(); i++){
		int id = q[x][i].id,BIG = q[x][i].x;
		ans[id] = BIG*(siz[x]-1)+query(root[x],1,3e5,dep[x]+1,3e5);
	}
}
int main()
{
	n = read(); m = read();
	for (int i = 1,u,v; i < n; i++)
		u = read(),v = read(),add(u,v),add(v,u);
	dfs(1,0);
	for (int i = 1,p,k,ace; i <= m; i++)
	{
		p = read(); k = read();
		ace = (dep[p]-k<=0)?(dep[p]-1):k;
		q[p].push_back((que){i,ace});
//		printf("%d\n",ace);
	}
	solve(1);
	for (int i = 1; i <= m; i++)
		printf("%d\n",ans[i]);
	return 0;
}
2023/11/25 14:23
加载中...