列表

详情


NC235715. 正经人谁吃泡菜肥牛啊?

描述

在吃完联动活动的泡菜肥牛汉堡之后非常感动,仿佛混沌初开,宇宙爆炸,万物苏生,闪灵斩开光明与黑暗,弑君者被崖心一套绳索勾进了防卫点,从医院回到集训队种了一棵泡菜肥牛树,仅仅过了一个月,泡菜肥牛树就成长到了完美的境界,泡菜的微辣,肥牛的香味,以及奇异的酱料的酸味巧妙的混合在一起。

作为泡菜肥牛树的养育者,在这个收获的季节,开始收获树上的汉堡。

我们假设泡菜肥牛树的根节点为,树的大小为,每个结点上都长出了丰饶的汉堡,并且每个汉堡都拥有对应的泡菜肥牛值,Azir对泡菜肥牛汉堡非常眼馋,问了共计q个问题,他的问题都是在x作为根节点的子树上,有多少个汉堡的泡菜肥牛值不大于k(包括根节点)

输入描述

第一行输入节点数

第二行是输入个整数泡菜肥牛值

接下来行,每行包括两个数表示相连

接下来一行输入一个整数,表示Azir的询问数

之后的q行每行输入两个整数,表示Azir询问的是以x为根结点的子树中有多少结点的泡菜肥牛值不大于k(包括x这个结点)

输出描述

输出q行,表示在当前询问中的以x为根结点的子树中有多少结点的泡菜肥牛值不大于k(包括x这个结点)

示例1

输入:

4
1 2 3 1
1 2
1 3
3 4
3
1 3
3 1
2 2

输出:

4
1
1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 1705ms, 内存消耗: 151056K, 提交时间: 2022-07-04 22:15:08

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
vector<int>g[N];
int n,a[N],tr[N],son[N],sz[N],idx,hd[N],ret,u,v,q;
struct edge{
	int v,nxt;
}e[N<<1];
struct ans{
	int x,y,ans;
}ans[N];
void add_edge(int u,int v)
{
	e[++idx]=(edge){v,hd[u]};
	hd[u]=idx;
}
void update(int x,int y)
{
	for(int i=x;i<N;i+=i&-i)
		tr[i]+=y;
}
int ask(int x)
{
	for(ret=0;x;x-=x&-x)
		ret+=tr[x];
	return ret;
}
void dfs1(int x,int y)
{
	sz[x]=1;
	for(int i=hd[x];i;i=e[i].nxt)
	{
		if(e[i].v==y)
			continue;
		dfs1(e[i].v,x);
		sz[x]+=sz[e[i].v];
		if(sz[e[i].v]>sz[son[x]])
			son[x]=e[i].v;
	}
}
void calc(int x,int y,int z)
{
	update(a[x],z);
	for(int i=hd[x];i;i=e[i].nxt)
		if(e[i].v!=y)
			calc(e[i].v,x,z);
}
void dsu(int x,int y,int z)
{
	for(int i=hd[x];i;i=e[i].nxt)
		if(e[i].v!=y&&e[i].v!=son[x])
			dsu(e[i].v,x,1);
	if(son[x])
		dsu(son[x],x,0);
	update(a[x],1);
	for(int i=hd[x];i;i=e[i].nxt)
		if(e[i].v!=son[x]&&e[i].v!=y)
			calc(e[i].v,x,1);
	for(int i=0;i<(int)g[x].size();i++)
		ans[g[x][i]].ans=ask(ans[g[x][i]].y);
	if(z)
		calc(x,y,-1);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",a+i);
	for(int i=1;i<n;i++)
	{
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs1(1,0);
	scanf("%d",&q);
	for(int i=1;i<=q;i++)	
	{
		scanf("%d%d",&ans[i].x,&ans[i].y);
		g[ans[i].x].push_back(i);
	} 
	dsu(1,0,0);
	for(int i=1;i<=q;i++)
		printf("%d\n",ans[i].ans);
}

上一题