题目

\(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. bzoj 4942: [Noi2017]整数

    Description Solution 加法减法可以分开考虑,如果只有加法的话,直接暴力进位复杂度是对的 询问的时候就是把两个二进制数做差,判断第 \(k\) 位的取值 实际上我们只需要判断 \(1 ...

  2. YII框架一个请求的生命周期

    用户向入口脚本 web/index.php 发起请求. 入口脚本加载应用配置并创建一个应用实例去处理请求. 应用通过请求组件解析请求的路由. 应用创建一个控制器实例去处理请求. 控制器创建一个操作实例 ...

  3. What is the difference between modified duration, effective duration and duration?

    Macaulay Duration (traditionally just called Duration) The formula usually used to calculate a bond' ...

  4. js校验数字是否为小数

    js校验数字是否为小数: function checkDot(c) {c = parseFloat(c); -]?[-]*\.[-]*[-]+$/; return r.test(c); }

  5. springboot1.5.10兼容高版本6.1.1elasticsearch

    1.引入依赖 <dependency> <groupId>org.elasticsearch</groupId> <artifactId>elastic ...

  6. Service的启动流程源码跟踪

    前言: 当我们在一个Activity里面startService的时候,具体的执行逻辑是怎么样的?需要我们一步步根据源码阅读. 在阅读源码的时候,要关注思路,不要陷在具体的实现细节中,一步步整理代码的 ...

  7. 移动web开发ajax缓存操作

    移动web开发过程中网速是必须考虑的一个因素,所以一般是尽可能的在本地存储数据,避免弱网环境下请求数据失败导致页面没有内容的情况. 前后端分离是web开发的必然趋势,在PC端我们有时甚至为了避免aja ...

  8. 洛谷P1024 一元三次方程求解(数学)

    题意 题目链接 Sol 本来是一道好的公式题. 然后输出只要保留两位小数?? 直接上不就赢了嘛.. #include<bits/stdc++.h> #define LL long long ...

  9. JavaScript的重载(通过argument.length)

    偶然间在博客园看到的关于js的重载(重载就是一组具有相同名字.不同参数列表,实现不同操作的函数或方法)问题,作为初学者,在看红宝书的时候,记得书中有概念说明js是没有重载的 所以,觉得有必要把这一段 ...

  10. 05_dubbo_aop

    [对这行代码进行源码分析] ExtensionLoader<Protocol> loader = ExtensionLoader.getExtensionLoader(Protocol.c ...