题目

\(dsu\ on\ tree\)的板子题了

\(dsu\ on\ tree\)本质上一种优秀通过轻重链剖分优化到\(O(nlogn)\)的暴力

一般用来解决没有修改的允许离线的子树查询问题

首先先来处理出每一个节点的重儿子

接下来按照如下的顺序统计

  1. 递归处理当前节点的所有轻儿子

  2. 递归处理重儿子

  3. 遍历一遍整棵子树,统计信息(但是不用访问当前点的重儿子)

  4. 如果这个节点是重儿子,就返回,否则的话就清空所有信息

所以第三步,不用访问当前点的重儿子就是因为在第四步的时候重儿子没有被清空

至于这道题我们数颜色的时候开一个树状数组,每次存储颜色的桶数量发生变化,就在树状数组里修改相应的位置

查一个后缀和就好了

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define re register
#define lowbit(x) ((x)&(-x))
#define maxn 100005
inline int read() {
int x=0;char c=getchar();while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int n,m,num,__,Son,tot;
struct Ask{int x,k,rk;}q[maxn];
struct E{int v,nxt;}e[maxn<<1];
int son[maxn],sum[maxn],deep[maxn],col[maxn];
int dfn[maxn],c[maxn],tax[maxn],Ans[maxn],head[maxn];
inline int cmp(Ask A,Ask B) {return dfn[A.x]<dfn[B.x];}
inline void C(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
inline void add(int x,int val) {for(re int i=x;i;i-=lowbit(i)) c[i]+=val;}
inline int ask(int x) {int now=0;for(re int i=x;i<=n;i+=lowbit(i)) now+=c[i];return now;}
void dfs1(int x) {
sum[x]=1;int maxx=-1;
for(re int i=head[x];i;i=e[i].nxt) {
if(deep[e[i].v]) continue;
deep[e[i].v]=deep[x]+1,dfs1(e[i].v);
sum[x]+=sum[e[i].v];
if(sum[e[i].v]>maxx) maxx=sum[e[i].v],son[x]=e[i].v;
}
}
void dfs2(int x) {
for(re int i=head[x];i;i=e[i].nxt)
if(deep[e[i].v]>deep[x]&&son[x]!=e[i].v) dfs2(e[i].v);
if(son[x]) dfs2(son[x]);
dfn[x]=++__;
}
void calc(int x,int opt) {
if(tax[col[x]]) add(tax[col[x]],-1);
tax[col[x]]+=opt;
if(tax[col[x]]) add(tax[col[x]],1);
for(re int i=head[x];i;i=e[i].nxt)
if(deep[e[i].v]>deep[x]&&Son!=e[i].v) calc(e[i].v,opt);
}
void dfs(int x,int opt) {
for(re int i=head[x];i;i=e[i].nxt)
if(deep[e[i].v]>deep[x]&&son[x]!=e[i].v)
dfs(e[i].v,0);
if(son[x]) dfs(son[x],1);
Son=son[x];calc(x,1);Son=0;
while(q[tot].x==x) {
Ans[q[tot].rk]=ask(q[tot].k);tot++;
}
if(!opt) calc(x,-1);
}
int main() {
n=read(),m=read();
for(re int i=1;i<=n;i++) col[i]=read();
for(re int x,y,i=1;i<n;i++) x=read(),y=read(),C(x,y),C(y,x);
deep[1]=1,dfs1(1),dfs2(1);
for(re int i=1;i<=m;i++) q[i].rk=i,q[i].x=read(),q[i].k=read();
std::sort(q+1,q+m+1,cmp);tot=1;dfs(1,1);
for(re int i=1;i<=m;i++) printf("%d\n",Ans[i]);
return 0;
}

「CF375D Tree and Queries」的更多相关文章

  1. CF375D Tree and Queries

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

  2. 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++) 调了两个小时 这题要求维护& ...

  3. CF375D Tree and Queries 题解

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

  4. 【题解】 Luogu CF375D Tree and Queries

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

  5. cf375D. Tree and Queries(莫队)

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

  6. 【题解】CF375D Tree and Queries

    Link \(\text{Solution:}\) 讲实话这题有点烦,不知道为啥改了下\(\text{dfs}\)就过了--原版本\(dfs\)好像没啥错啊-- 其实对于子树问题,我们求出原来树的\( ...

  7. #10471. 「2020-10-02 提高模拟赛」灌溉 (water)

    题面:#10471. 「2020-10-02 提高模拟赛」灌溉 (water) 假设只有一组询问,我们可以用二分求解:二分最大距离是多少,然后找到深度最大的结点,并且把它的\(k\)倍祖先的一整子树删 ...

  8. 众安「尊享e生」果真牛的不可一世么?

    近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...

  9. XCActionBar 「Xcode 中的 Alfred」

    下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...

随机推荐

  1. linux设置别名

    1.查看别名: alias 2.临时设置别名 alias show='ls -al' 3.永久生效 vi 家目录/.bashrc alias mmm='mysql -uroot -p' 4.删除别名 ...

  2. Java复习第四天

    1.Object类 (1)Object是类层次结构的根类,所有的类都直接或者间接的继承自Object类. (2)Object类的构造方法有一个,并且是无参构造:子类构造方法默认访问父类的构造是无参构造 ...

  3. TortoiseGit记住用户名&密码

    配置并安装好git之后鼠标右键: 在全局配置文件末尾添加一行: [credential] helper = store *主意保存时以utf-8格式保存,否则中文可能会乱码,这样下次只需输入一次用户名 ...

  4. forward和redirect请求方式

    之前一直对forward和redirect有点疑问,现在练习一下加深点记忆,理解理解,forward是一次请求,在一个request范围内,而redirect是二次请求 实例: @Controller ...

  5. 限流(三)Redis + lua分布式限流

    一.简介 1)分布式限流 如果是单实例项目,我们使用Guava这样的轻便又高性能的堆缓存来处理限流.但是当项目发展为多实例了以后呢?这时候我们就需要采用分布式限流的方式,分布式限流可以以redis + ...

  6. windows下es安装教程

    es安装 1.es下载地址:https://www.elastic.co/downloads/past-releases 2.使用es需要先安装好jdk,注意es版本和jdk版本的兼容问题,es6.1 ...

  7. javaweb之请求的转发和重定向

    1.什么是请求转发和请求重定向? 请求转发: xxServlet收到请求,然后直接转发给yyServlet,然后yyServlet返回给客户端.整个过程中,客户端发出一个请求,收到一个响应. 重定向: ...

  8. springMVC基于注解的控制器

    springMVC基于注解的控制器 springMVC基于注解的控制器的优点有两个: 1.控制器可以处理多个动作,这就允许将相关操作写在一个类中. 2.控制器的请求映射不需要存储在配置文件中.使用re ...

  9. 结构型--代理模式(Proxy)

    一.代理模式是什么? 代理模式属于GOF23设计模式中结构型中的设计模式,通过代理对象来屏蔽(部分或者屏蔽)对真实对象的直接访问,下图为UML图: 在代理模式中组件包括:抽象角色接口.代理角色类.真实 ...

  10. css-css的基本选择器(三种)

    ** 要对哪个标签里面的数据进行操作 (1)标签选择器 div { background-color:red; color:blue; } (2)class选择器 * 每个HTML标签中都有一个属性 ...