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. JS开发必须知道的41个技巧

    JS是前端的核心,但有些使用技巧你还不一定知道:本文梳理了JS的41个技巧,帮助大家提高JS的使用技巧: Array 1.数组交集 普通数组 const arr1 = [, , , , , ,],ar ...

  2. MySql密码的问题

    由于长时间没使用过MySql了,也由于之前没有做笔记的习惯,晚上因为MySQL的密码问题导致数据库长时间没连上.纠结了这么久还是决定记录下来,毕竟安装的东西多了,这年头到处都是密码,加上时间一长,很容 ...

  3. 01 fs模块

    1 fs.readFile 异步执行函数 /** fs 读取文件相对路径是相对终端命令行所在的路径 process.cwd()返回终端命令行的绝对路径 * */ fs = require('fs') ...

  4. 一文搞懂WordPress建站

    文章首发于:https://zouwang.vip/ 日日夜夜的等待,WordPress建站教程终于来了.本篇文章适用于第一次建站的小白,帮助你从零搭建起一个属于自己的网站,既然是从零,那么我就会带着 ...

  5. 【小白学PyTorch】8 实战之MNIST小试牛刀

    文章来自微信公众号[机器学习炼丹术].有什么问题都可以咨询作者WX:cyx645016617.想交个朋友占一个好友位也是可以的~好友位快满了不过. 参考目录: 目录 1 探索性数据分析 1.1 数据集 ...

  6. 用于测试 JsonAnalyzer2 1.01版的测试用例

    14. 原文={"animal":"ca,t","color":"ora:nge","isMale" ...

  7. CVE-2020-0796(永恒之黑)漏洞复现

    声明:仅供学习与参考,请勿用于非法用途(后果自负) 一.影响范围(需关闭 Win10 防火墙): Windows 10 Version 1903 for 32-bit Systems Windows ...

  8. Java并发编程之闭锁与栅栏

    一.前言 闭锁与栅栏是在多线程编程中的概念,因为在多线程中,我们不能控制线程的执行状态,所以给线程加锁,让其按照我们的想法有秩序的执行. 闭锁 CountDownLatch,实例化时需要传入一个int ...

  9. python之requests.session()使用

    背景:使用requests.session会话对象先登录至豆瓣网,再进入“我的豆瓣”. 首先说一下,为什么要进行会话保持的操作? requests库的session会话对象可以跨请求保持某些参数. 说 ...

  10. liunx配置本地yum源和更新aliyun yum源

    1.挂载DVD光盘到/mnt   因为配置时候路径名里面不能有空格,否则不能识别 [root@ mnt]# mount   /dev/cdrom   /mnt [root@ mnt]# umount ...