「CF375D Tree and Queries」
\(dsu\ on\ tree\)的板子题了
\(dsu\ on\ tree\)本质上一种优秀通过轻重链剖分优化到\(O(nlogn)\)的暴力
一般用来解决没有修改的允许离线的子树查询问题
首先先来处理出每一个节点的重儿子
接下来按照如下的顺序统计
递归处理当前节点的所有轻儿子
递归处理重儿子
遍历一遍整棵子树,统计信息(但是不用访问当前点的重儿子)
如果这个节点是重儿子,就返回,否则的话就清空所有信息
所以第三步,不用访问当前点的重儿子就是因为在第四步的时候重儿子没有被清空
至于这道题我们数颜色的时候开一个树状数组,每次存储颜色的桶数量发生变化,就在树状数组里修改相应的位置
查一个后缀和就好了
代码
#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」的更多相关文章
- CF375D Tree and Queries
题意翻译 给出一棵 n 个结点的树,每个结点有一个颜色 c i . 询问 q 次,每次询问以 v 结点为根的子树中,出现次数 ≥k 的颜色有多少种.树的根节点是1. 感谢@elijahqi 提供的翻译 ...
- 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++) 调了两个小时 这题要求维护& ...
- CF375D Tree and Queries 题解
感觉CF的题目名都好朴素的样子 你谷链接 首先这题显然是个dsu on tree 但是我不会. 其次这题显然是个莫队.这我会啊! 然后会发现好像不是很对劲.因为每次询问都有一个k,貌似和传统的莫队数颜 ...
- 【题解】 Luogu CF375D Tree and Queries
原题传送门 这道题要用树链剖分,我博客里有对树链剖分的详细介绍 我博客中对莫队的详细介绍 莫队好题 我一上来想写线段树,随后觉得不好写并弃坑 我们可以看见没有修改操作,钦定莫队 但这是在树上,所以不能 ...
- cf375D. Tree and Queries(莫队)
题意 题目链接 给出一棵 n 个结点的树,每个结点有一个颜色 c i . 询问 q 次,每次询问以 v 结点为根的子树中,出现次数 ≥k 的颜色有多少种.树的根节点是1. Sol 想到了主席树和启发式 ...
- 【题解】CF375D Tree and Queries
Link \(\text{Solution:}\) 讲实话这题有点烦,不知道为啥改了下\(\text{dfs}\)就过了--原版本\(dfs\)好像没啥错啊-- 其实对于子树问题,我们求出原来树的\( ...
- #10471. 「2020-10-02 提高模拟赛」灌溉 (water)
题面:#10471. 「2020-10-02 提高模拟赛」灌溉 (water) 假设只有一组询问,我们可以用二分求解:二分最大距离是多少,然后找到深度最大的结点,并且把它的\(k\)倍祖先的一整子树删 ...
- 众安「尊享e生」果真牛的不可一世么?
近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...
- XCActionBar 「Xcode 中的 Alfred」
下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...
随机推荐
- [转]Web API Introduction to OData Services using ASP.NET Web API
本文转自:http://mahedee.net/tag/web-api/ What is OData? OData Stands for Open Data Protocol. It is a dat ...
- bitbucket 源代码托管
5个人以下可以免费使用,不限制仓库的数量; 国外的注册需要开启蓝灯FQ; 1.注册账号 maanshancss w1-g1@qq.com;创建仓库; 然后拷贝现有项目 然后提交 然后push; 2.写 ...
- T-SQL语句创建表
USE E_Market --指定当前所操作的数据库 GO CREATE TABLE 表名 ( BID int identity (1,1)NOT NULL, BNAME varch ...
- OC与JS交互之JavaScriptCore
JavaScriptCore提供了JavaScript和Objective-C桥接的Obj-C API.JavaScriptCore提供了让我们脱离UIWebView执行JavaScript脚本的能力 ...
- Java API 之 正则表达式
一.基本概念 在项目中我们经常性做的一件事是“匹配”字符串 比如: 1.我们要验证用户输入的手机号是否合法? 2.验证设置的密码是否符合规则? 3.或者替换指定字符串中的一些内容. 这么一看,似乎正则 ...
- 流畅的python和cookbook学习笔记(五)
1.随机选择 python中生成随机数使用random模块. 1.从序列中随机挑选元素,使用random.choice() >>> import random >>> ...
- shell变量类型和运算符
一.shell变量的应用 1.shell变量的种类 ①用户自定义变量:由用户自己定义,修改和使用 ②预定义变量:bash预定义的特殊变量,不能直接修改 ③位置变量:通过命令行给程序传递执行参数 二.变 ...
- 第5章 css与背景相关的样式background
background-origin 设置元素背景图片的原始起始位置. 语法: background-origin : border-box | padding-box | content-box; 参 ...
- java TreeSet 实现存自定义不可重复数据
本文主要是介绍一下java集合中的比较重要的Set接口下的可实现类TreeSet TreeSet类,底层用二叉树的数据结构 * 集合中以有序的方式插入和抽取元素. * 添加到TreeSet中的元素必须 ...
- csharp:.net 3.5 using System.Runtime.Serialization.Json read json
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...