ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【CF375D】Tree and Queries

2021-06-15 14:32:25  阅读:180  来源: 互联网

标签:head int siz Tree tot son ++ CF375D Queries


题目

题目链接:https://codeforces.com/problemset/problem/375/D
给定一棵 \(n\) 个节点的有根树,节点有颜色,\(m\) 次询问一个点的子树内出现次数 \(\geq k\) 的颜色数有多少。
\(n\leq 10^5\)。

思路

dsu on tree 板子题。
本来太板子不想写的,但是因为太久没写了就水了一道题。
直接维护一个桶表示出现次数等于下标的颜色数量即可。
时间复杂度 \(O(n\log n+m)\)。

代码

#include <bits/stdc++.h>
#define mp make_pair
#define fi first
#define se second
using namespace std;

const int N=100010;
int n,m,tot,head[N],a[N],cnt[N],sum[N],ans[N],siz[N],son[N],id[N],rk[N];
vector<pair<int,int> > ask[N];

struct edge
{
	int next,to;
}e[N*2];

void add(int from,int to)
{
	e[++tot]=(edge){head[from],to};
	head[from]=tot;
}

void dfs1(int x,int fa)
{
	siz[x]=1;
	for (int i=head[x];~i;i=e[i].next)
	{
		int v=e[i].to;
		if (v!=fa)
		{
			dfs1(v,x); siz[x]+=siz[v];
			if (siz[v]>siz[son[x]]) son[x]=v;
		}
	}
}

void dfs2(int x,int fa,bool flag)
{
	id[x]=++tot; rk[tot]=x;
	for (int i=head[x];~i;i=e[i].next)
	{
		int v=e[i].to;
		if (v!=fa && v!=son[x]) dfs2(v,x,1);
	}
	if (son[x]) dfs2(son[x],x,0);
	cnt[a[x]]++; sum[cnt[a[x]]]++;
	if (son[x])
		for (int i=id[x]+1;i<id[son[x]];i++)
			cnt[a[rk[i]]]++,sum[cnt[a[rk[i]]]]++;
	for (int i=0;i<ask[x].size();i++)
		ans[ask[x][i].se]=sum[ask[x][i].fi];
	if (flag)
		for (int i=id[x];i<id[x]+siz[x];i++)
			sum[cnt[a[rk[i]]]]--,cnt[a[rk[i]]]--;
}

int main()
{
	memset(head,-1,sizeof(head));
	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);
	}
	for (int i=1,x,y;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		ask[x].push_back(mp(y,i));
	}
	tot=0; 
	dfs1(1,0); dfs2(1,0,1);
	for (int i=1;i<=m;i++) cout<<ans[i]<<"\n";
	return 0;
}

标签:head,int,siz,Tree,tot,son,++,CF375D,Queries
来源: https://www.cnblogs.com/stoorz/p/14885357.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有