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的后代是否可以经过调整变成一个回文串. 做法: 推断能否够构成一个回文串的话,仅仅须要知道是否有大于一个 ...
随机推荐
- 2019-3-9-通过-frp-开启服务器打开本地的-ZeroNet-服务器外网访问
title author date CreateTime categories 通过 frp 开启服务器打开本地的 ZeroNet 服务器外网访问 lindexi 2019-03-09 11:47:4 ...
- 树莓派 msmtp和mutt 的安装和配置
1,安装mutt sudo apt-get install mutt 2,安装msmtp sudo apt-get install msmtp 3,设置mutt /etc/Muttrc # 系统全局设 ...
- Swagger详解(SpringBoot+Swagger集成)(转)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/ai_miracle/article/de ...
- 【Kickstart】2018 Round (Practice ~ C)
Practice Round Problem A GBus count (9pt/15pt) (2019年1月14日,kickstart群每日一题) 题意:有一条笔直的大路,上面有城市编号从 1 开始 ...
- Java8 的一些新特性的学习理解
近期在学习队列相关的一些知识,在学习过程中发现Iterable<T>接口中新增了两个新的方法,出于好奇,就想知道这是什么东东,干什么用的.俗话说:实践出真知,所以就有了以下反复的测试. 先 ...
- LeetCode--044--通配符匹配(java)*
给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). 两个字符串完全匹配才算 ...
- drf 搜索功能
from django_filters.rest_framework import DjangoFilterBackend from rest_framework import viewsets fr ...
- OC + RAC (三) 信号中的信号
-(void)_test3{ RACSubject *signalofsignal = [RACSubject subject]; //信号中的信号(也就是发送的数据是信号) RACSubject * ...
- 演示Git使用
对于新建的repository,第一次提交,完整过程: 13643@DESKTOP-K6CS6SE MINGW64 ~/Desktop/555 $ ls Readme.md run.py 13643@ ...
- python 全栈开发,Day53(jQuery的介绍,jQuery的选择器,jQuery动画效果)
01-jQuery的介绍 1.为什么要使用jQuery 在用js写代码时,会遇到一些问题: window.onload 事件有事件覆盖的问题,因此只能写一个事件. 代码容错性差. 浏览器兼容性问题. ...