Codeforces 375D D. Tree and Queries
题意:
给一棵树,每个节点有一个颜色,询问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的更多相关文章
- codeforces 375D:Tree and Queries
Description You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. ...
- Codeforces 375 D Tree and Queries
Discription You have a rooted tree consisting of n vertices. Each vertex of the tree has some color. ...
- Codeforces 375D Tree and Queries(DFS序+莫队+树状数组)
题目链接 Tree and Queries 题目大意 给出一棵树和每个节点的颜色.每次询问$vj, kj$ 你需要回答在以$vj$为根的子树中满足条件的的颜色数目, 条件:具有该颜色的节点数量至少 ...
- CodeForces 375D Tree and Queries 莫队||DFS序
Tree and Queries 题意:有一颗以1号节点为根的树,每一个节点有一个自己的颜色,求出节点v的子数上颜色出现次数>=k的颜色种类. 题解:使用莫队处理这个问题,将树转变成DFS序区间 ...
- [Codeforces Round #221 (Div. 1)][D. Tree and Queries]
题目链接:375D - Tree and Queries 题目大意:给你一个有n个点的树,每个点都有其对应的颜色,给出m次询问(v,k),问v的子树中有多少种颜色至少出现k次 题解:先对所有的询问进行 ...
- codeforces 570 D. Tree Requests 树状数组+dfs搜索序
链接:http://codeforces.com/problemset/problem/570/D D. Tree Requests time limit per test 2 seconds mem ...
- 【19.77%】【codeforces 570D】Tree Requests
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- Problem - D - Codeforces Fix a Tree
Problem - D - Codeforces Fix a Tree 看完第一名的代码,顿然醒悟... 我可以把所有单独的点全部当成线,那么只有线和环. 如果全是线的话,直接线的条数-1,便是操作 ...
- codeforces 570 D Tree Requests
题意:给出一棵树.每一个结点都有一个字母,有非常多次询问,每次询问.以结点v为根的子树中高度为h的后代是否可以经过调整变成一个回文串. 做法: 推断能否够构成一个回文串的话,仅仅须要知道是否有大于一个 ...
随机推荐
- MacBook Pro修改hosts
访达前往:/etc/hosts 将hosts复制到桌面修改保存 替换 附Windows hosts文件位置: C:\windows\System32\drivers\etc
- rabbit-c编译 vs2013
需要openssl的库
- git@github.com出现Permission denied (publickey)
上传项目的时候出现Permission denied (publickey)这个问题 解决方案如下: 看本地的.git/config设置的仓库url地址和github使用的链接地址是否一致如下图,如u ...
- sqlmap 基本使用步骤(一)
列出数据据信息:python sqlmap.py -u "http://ctf5.shiyanbar.com/web/index_3.php?id=1" --dbs 列出当前数据库 ...
- HTML5 中list 和datalist实例
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 通过反射获取方法的参数名称(JDK8以上支持)
方法的参数名,在很多时候我们是需要反射得到的.但是在java8之前,代码编译为class文件后,方法参数的类型是固定的,但参数名称却丢失了,这和动态语言严重依赖参数名称形成了鲜明对比.(java是静态 ...
- django之静态文件的设置
一:静态文件 Django中提供了一种解析的方式配置静态文件路径.静态文件可以放在项目根目录下,也可以放在应用的目录下,由于有些静态文件在项目中是通用的,所以推荐放在项目的根目录下,方便管理. 为了提 ...
- B1001. 害死人不偿命的(3n + 1)猜想
题目描述 卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n + 1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在19 ...
- NVMe固态硬盘工具箱使用说明
https://www.bilibili.com/read/cv562989/ 浦科特NVMe固态硬盘工具箱使用说明 数码 2018-6-7 687阅读7点赞3评论 浦科特已经推出针对NVMe固态硬盘 ...
- 历时小半年总结之JAVA
一.JavaSE 1.多线程 (1).进程与线程的区别? 答:进程是所有线程的集合,每一个线程是进程中的一条执行路径,线程只是一条执行路径. (2).为什么要用多线程? 答:提高程序效率 (3).多线 ...