传送门

题意:

给一棵树,每个节点有一个颜色,询问x为根的子树,出现次数大于等于k的颜色个数。

输入格式:

第一行 2 个数 n,m 表示节点数和询问数。

接下来一行 n 个数,第 i 个数 ci ​表示节点 i 的颜色。

接下来 n-1 行,每行两个数 a,b 表示一条边。

接下来 m 行,每行两个数 x,k 表示一组询问。

数据范围: $n.m,c,k \in [1,10^5]$

显然可以 $dsu\ on\ tree$

可以用权值树状数组直接维护当前每个出现次数大于等于 $k$ 的颜色数量

但是因为每次修改都只有加 $1$ 或减 $1$

所以可以直接维护 $ans[i]$ 表示出现次数大于等于 $i$ 的颜色数量

具体代码就可以这样维护:

//cnt是每种颜色当前出现次数
inline void ins(int c) { cnt[c]++; ans[cnt[c]]++; }
inline void del(int c) { ans[cnt[c]]--; cnt[c]--; }

其他就是 $dsu\ on\ tree$ 的基本操作了

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=2e6+;
int fir[N],from[N<<],to[N<<],cntt;
inline void add(int &a,int &b) { from[++cntt]=fir[a]; fir[a]=cntt; to[cntt]=b; }
int n,m,col[N],Ans[N];
struct dat{
int x,k,id;//以节点x为根,出现次数大于等于k的询问,编号为id
inline bool operator < (const dat &tmp) const {
return x<tmp.x;
}
}d[N];//存询问并准备把询问按x排序
int sz[N],son[N];
void dfs1(int x,int fa)
{
sz[x]=;
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(v==fa) continue;
dfs1(v,x); sz[x]+=sz[v];
if(sz[v]>sz[son[x]]) son[x]=v;
}
}
int id[N],dfs_clock,cnt[N],ans[N];//id是dfs序为i的节点编号
inline void ins(int c) { cnt[c]++; ans[cnt[c]]++; }
inline void del(int c) { ans[cnt[c]]--; cnt[c]--; }
inline void work(int x)//处理与节点x有关的询问
{
for(int i=lower_bound(d+,d+m+,(dat){x,,})-d ; d[i].x==x ; i++)
Ans[d[i].id]=ans[d[i].k];
}
void dfs2(int x,int fa,bool flag)//flag判断是否要清空子树
{
id[++dfs_clock]=x; int L=dfs_clock;//L是轻儿子子树左区间
if(!son[x]) { ins(col[x]); work(x); if(!flag) del(col[x]); return; }
//注意上面对于叶节点的特判中要先ins再work再del
for(int i=fir[x];i;i=from[i])
{
int &v=to[i]; if(v==fa||v==son[x]) continue;
dfs2(v,x,);
}
int R=dfs_clock;//轻儿子子树右区间
dfs2(son[x],x,);
for(int i=L;i<=R;i++) ins( col[id[i]] );
work(x);
if(!flag) for(int i=L;i<=dfs_clock;i++) del( col[id[i]] );//注意清除的区间不是[L,R]
}
int main()
{
n=read(),m=read(); int a,b;
for(int i=;i<=n;i++) col[i]=read();
for(int i=;i<n;i++)
{
a=read(),b=read();
add(a,b); add(b,a);
}
dfs1(,);
for(int i=;i<=m;i++) d[i].x=read(),d[i].k=read(),d[i].id=i;
sort(d+,d+m+);//离散化
dfs2(,,);
for(int i=;i<=m;i++) printf("%d\n",Ans[i]);
return ;
}

Codeforces 375D D. Tree and Queries的更多相关文章

  1. codeforces 375D:Tree and Queries

    Description You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. ...

  2. Codeforces 375 D Tree and Queries

    Discription You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. ...

  3. Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)

    题目链接  Tree and Queries 题目大意  给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...

  4. CodeForces 375D Tree and Queries 莫队||DFS序

    Tree and Queries 题意:有一颗以1号节点为根的树,每一个节点有一个自己的颜色,求出节点v的子数上颜色出现次数>=k的颜色种类. 题解:使用莫队处理这个问题,将树转变成DFS序区间 ...

  5. [Codeforces Round #221 (Div. 1)][D. Tree and Queries]

    题目链接:375D - Tree and Queries 题目大意:给你一个有n个点的树,每个点都有其对应的颜色,给出m次询问(v,k),问v的子树中有多少种颜色至少出现k次 题解:先对所有的询问进行 ...

  6. codeforces 570 D. Tree Requests 树状数组+dfs搜索序

    链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...

  7. 【19.77%】【codeforces 570D】Tree Requests

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. Problem - D - Codeforces Fix a Tree

    Problem - D - Codeforces  Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...

  9. codeforces 570 D Tree Requests

    题意:给出一棵树.每一个结点都有一个字母,有非常多次询问,每次询问.以结点v为根的子树中高度为h的后代是否可以经过调整变成一个回文串. 做法: 推断能否够构成一个回文串的话,仅仅须要知道是否有大于一个 ...

随机推荐

  1. docker安装各种坑

    今天记录一下之前安装docker遇到的各种坑. 我们从http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/这个网站下载. 下 ...

  2. 了解Greenplum(1)

    了解系列废话: 数据管理系统实现,以Greenplum作为课后实验,这里将实验报告贴出来,纯粹灌水. 1.Greenplum架构 如上图所示,GP的基本结构是单master,多slave节点,客户端连 ...

  3. oracle 汇编04

    General-Purpose Instructions The general-purpose instructions perform basic data movement, memory ad ...

  4. koa2 进阶网站

    http://www.ruanyifeng.com/blog/2017/08/koa.html  阮一峰 https://www.itying.com/koa/ koa2中文网 https://blo ...

  5. 专家告诉你!如何避免黑客BGP劫持?

    BGP前缀劫持是针对Internet组织的持久威胁,原因是域间路由系统缺乏授权和身份验证机制. 仅在2017年,数千起路由事件导致代价高昂的中断和信息拦截,而问题的确切程度未知.尽管在过去20年中已经 ...

  6. 黑客已经瞄准5G网络,如何防止LTE网络攻击?

    黑客是如何攻击5G网络?即使5G进行大规模应用,LTE技术会被淘汰吗?那么我们应该如何防止LTE网络攻击? 5G-网络黑客 即将推出的5G网络也可能容易受到这些攻击,来自中国网络安全研究人员表示,尽管 ...

  7. Task3.特征选择

    参考:https://www.jianshu.com/p/f3b92124cd2b 互信息 衡量两个随机变量之间的相关性,两个随机变量相关信息的多少. 随机变量就是随机试验结果的量的表示,可以理解为按 ...

  8. 饿了么CTO张雪峰:允许90后的技术人员“浮躁“一点

    编者按:今年4月,饿了么正式加入了阿里新零售战队,进一步加速其在本地生活市场的扩张速度.在创业9年的时间中,饿了么在外卖领域经历了真正的“从0到1”,尤其是在外卖平台的技术升级方面,越过了一个又一个的 ...

  9. MS4W安装教程

    简介 欢迎使用MS4W,这是由Gateway Geomatics开发的快速简便的安装程序,用于为Windows及其附带应用程序(如Geomoose.MapBender.Openlayers等)设置Ma ...

  10. Nexus Repository OSS 3安装配置使用

    Nexus Repository OSS 3是一个开源的仓库管理系统,提供了更加丰富的功能,而且安装.配置.使用起来也更加简单方便.OSS 3版本主要支持的仓库(Repository)包括如下: bo ...