Link

\(\text{Solution:}\)

讲实话这题有点烦,不知道为啥改了下\(\text{dfs}\)就过了……原版本\(dfs\)好像没啥错啊……

其实对于子树问题,我们求出原来树的\(dfs\)序列,则可以将它转化为一个序列问题。注意题目中说的是有根树,以\(1\)为根。

那么,我们一遍\(dfs\)求出序列后,把它插到询问里面,即更新为原序列。

注意,我们对应\(dfs\)序并不是原来的点,所以还需要一个数组\(rk\)维护映射\(point\to dfn\).

那么,对于维护,一种最直接的树状数组维护前缀和,复杂度套一个\(Log\).

另一种,我们考虑一下如何\(O(1)\)来维护,维护一个计数数组和\(sum\)数组。

每次更新一个数,如果是加,那么它原来次数的\(sum\)数组不用修改,在加完的\(sum\)数组处修改即可。因为这样是一路加过去的,手动模拟一下小样例更好理解。

对于删掉一个数,显然次数\(-1\),那么对应地它当前给\(sum\)数组的贡献就不再奏效,于是先把它的贡献清除掉,再将次数\(-1\).

我们通过以上做到了\(O(1)\)维护前缀和。

那么我们就可以莫队了。将询问离线,并分块排序,复杂度\(O(n\sqrt{n}).\)

玄学\(dfs\)真不知道怎么搞的,调了半天……

#include<bits/stdc++.h>
using namespace std;
const int MAXN=5e5+10;
int dfn[MAXN],n,m,tot,head[MAXN<<1];
int cnt[MAXN],ans[MAXN],dfstime,rk[MAXN];
int bl[MAXN],S,sum[MAXN],c[MAXN],siz[MAXN];
pair<int,int>Rem[MAXN];
struct edge{
int nxt,to;
}e[MAXN<<1];
inline void add(int x,int y){e[++tot].to=y;e[tot].nxt=head[x];head[x]=tot;}
void dfs(int x,int pre){
rk[dfn[x]=++dfstime]=x;
Rem[x].first=dfstime;siz[x]=1;
for(int i=head[x];i;i=e[i].nxt){
int j=e[i].to;
if(pre==j)continue;
dfs(j,x);siz[x]+=siz[j];
}
Rem[x].second=dfstime;
}
struct Q{
int l,r,k,id;
bool operator<(const Q&B)const{
if(bl[l]==bl[B.l])return r<B.r;
return bl[l]<bl[B.l];
}
}q[MAXN];
inline void inr(int x){++cnt[c[rk[x]]],++sum[cnt[c[rk[x]]]];}
inline void del(int x){--sum[cnt[c[rk[x]]]],--cnt[c[rk[x]]];} int main(){
scanf("%d%d",&n,&m);S=sqrt(n);
for(int i=1;i<=n;++i)scanf("%d",&c[i]),bl[i]=(i-1)/S+1;
for(int i=1;i<n;++i){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);add(y,x);
}
dfs(1,0);
for(int i=1,v;i<=m;++i){
scanf("%d%d",&v,&q[i].k);q[i].id=i;
q[i].l=dfn[v];q[i].r=dfn[v]+siz[v]-1;
}
sort(q+1,q+m+1);int l=1,r=0;
for(int i=1;i<=m;++i){
int ql=q[i].l,qr=q[i].r;
while(l<ql)del(l++);
while(l>ql)inr(--l);
while(r<qr)inr(++r);
while(r>qr)del(r--);
ans[q[i].id]=sum[q[i].k];
}
for(int i=1;i<=m;++i)printf("%d\n",ans[i]);
return 0;
}

【题解】CF375D Tree and Queries的更多相关文章

  1. CF375D Tree and Queries 题解

    感觉CF的题目名都好朴素的样子 你谷链接 首先这题显然是个dsu on tree 但是我不会. 其次这题显然是个莫队.这我会啊! 然后会发现好像不是很对劲.因为每次询问都有一个k,貌似和传统的莫队数颜 ...

  2. 【题解】 Luogu CF375D Tree and Queries

    原题传送门 这道题要用树链剖分,我博客里有对树链剖分的详细介绍 我博客中对莫队的详细介绍 莫队好题 我一上来想写线段树,随后觉得不好写并弃坑 我们可以看见没有修改操作,钦定莫队 但这是在树上,所以不能 ...

  3. CF375D Tree and Queries

    题意翻译 给出一棵 n 个结点的树,每个结点有一个颜色 c i . 询问 q 次,每次询问以 v 结点为根的子树中,出现次数 ≥k 的颜色有多少种.树的根节点是1. 感谢@elijahqi 提供的翻译 ...

  4. CF375D Tree and Queries(dsu on tree)

    思路 dsu on tree的板子,可惜人傻把 for(int i=fir[u];i;i=nxt[i]) 打成 for(int i=fir[u];i<=n;i++) 调了两个小时 这题要求维护& ...

  5. 「CF375D Tree and Queries」

    题目 \(dsu\ on\ tree\)的板子题了 \(dsu\ on\ tree\)本质上一种优秀通过轻重链剖分优化到\(O(nlogn)\)的暴力 一般用来解决没有修改的允许离线的子树查询问题 首 ...

  6. cf375D. Tree and Queries(莫队)

    题意 题目链接 给出一棵 n 个结点的树,每个结点有一个颜色 c i . 询问 q 次,每次询问以 v 结点为根的子树中,出现次数 ≥k 的颜色有多少种.树的根节点是1. Sol 想到了主席树和启发式 ...

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

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

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

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

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

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

随机推荐

  1. Android Studio 如何导出和导入自己的常用设置,避免重复制造轮子。加快开发速度

    Android Studio 如何导出和导入自己的常用设置,避免重复制造轮子.加快开发速度 作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 在使用 A ...

  2. css动画实现吃豆豆

    话不多说,直接上代码:(作为一个初学者写的代码,多么0基础都能看的懂吧.) HTML部分 <!DOCTYPE html> <html lang=en> <head> ...

  3. axure rp extension for chrome怎么用

    1)打开文件(原型图)的resources文件夹>chrome文件夹>将文件axure-chrome-extension.crx拉至谷歌浏览器的扩展程序页面,点击确定添加 2)提示出错时, ...

  4. 20190926-02Redis五大数据类型之Set 000 028

  5. MySql 实现数组根据下标获取对应值逻辑(array[i]逻辑)

    在使用sql模拟一段java逻辑开发时碰到有一段逻辑为从字符串数组中根据下标获取对应的值的情况,百度了一番没有发现有类似功能的函数和现成的实现方式,经过调试弄出来了,记录下来,以备参考 //举例:从数 ...

  6. String源码浅析

    如果问你,开发过程中用的最多的类是哪个?你可能回答是HashMap,一个原因就是HashMap的使用量的确很多,还有就是HashMap的内容在面试中经常被问起. 但是在开发过程中使用最多的类其实并不是 ...

  7. TP6.0中的密码验证逻辑、验证器的使用

    目录 1. 场景一:只有一个密码框,并且是可选项,留空不修改密码,不留空则修改密码 2. 场景二:两个密码框,修改密码时有新密码.确认密码,新密码框不为空时,确认密码才验证 1. 场景一:只有一个密码 ...

  8. linux基础:控制台

    图形界面切换至命令行界面:ctrl+alt+F1~F6 命令行界面切换至图形界面:startx linux一共有7个运行级别,可查看/etc/inittab文件: 0:停机(记住不要把initdefa ...

  9. kickstart半自动安装centos系统与pxe自动安装centos系统

    一.kickstart半自动安装centos系统 关闭防火墙,关闭selinux,使用system-config-kickstart生成kickstart配置文件,启动xmanger-Passive ...

  10. 记一次线上OOM问题分析与解决

    一.问题情况 最近用户反映系统响应越来越慢,而且不是偶发性的慢.根据后台日志,可以看到系统已经有oom现象. 根据jdk自带的jconsole工具,可以监视到系统处于堵塞时期.cup占满,活动线程数持 ...