cf375D. Tree and Queries

题意:

给你一颗有根树,每个点都有一个颜色,有m次询问,问以u为根的子树中,相同颜色数量超过k的有多少种颜色?

题解:

这个题做法很多,有莫队分块,这里用的dsu
就是对于一个子树内的颜色进行记录,为了方便我们后面的数量统计,对于一个子树中所有颜色出现次数,我们用树状数组来维护。比如颜色1已经出现了2两次,又出现了一次,那么我们就在树状数组中将2的位置减1,将位置3加1,树状数组维护的是颜色出现的数量。这样对于出现次数大于等于k的颜色种类,我们直接query(n)-query(l-1)即可,注意k有可能回比n大,所以要注意特判。
还有树状数组的维护尽可能在dfs过程中,不要单独再循环维护,不然常数太大

代码:

// Problem: D. Tree and Queries
// Contest: Codeforces - Codeforces Round #221 (Div. 1)
// URL: https://codeforces.com/contest/375/problem/D
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// Data:2021-09-03 12:55:52
// By Jozky#include <bits/stdc++.h>
#include <unordered_map>
#define debug(a, b) printf("%s = %d\n", a, b);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
clock_t startTime, endTime;
//Fe~Jozky
const ll INF_ll= 1e18;
const int INF_int= 0x3f3f3f3f;
void read(){};
template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar)
{x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...);
}
template <typename T> inline void write(T x)
{if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0');
}
void rd_test()
{#ifdef LOCALstartTime= clock();freopen("in.txt", "r", stdin);
#endif
}
void Time_test()
{#ifdef LOCALendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC);
#endif
}
const int maxn= 2e5 + 9;
int col[maxn];
vector<int> vec[maxn];
int siz[maxn];
int son[maxn], Son;
int ans[maxn];
void dfs(int u, int fa)
{siz[u]= 1;for (auto v : vec[u]) {if (v == fa)continue;dfs(v, u);siz[u]+= siz[v];if (siz[v] > siz[son[u]])son[u]= v;}
}
int va[maxn];vector<PII> q[maxn];
int f[maxn];
int num[maxn];
int n, m;
int lowbits(int x)
{return x & (-x);
}
void update(int pos, int val)
{for (int i= pos; i <= n; i+= lowbits(i)) {va[i]+= val;}
}
int query(int pos)
{int sum= 0;for (int i= pos; i; i-= lowbits(i)) {sum+= va[i];}return sum;
}
int query(int l, int r)
{if (l > r)return 0;return query(r) - query(l - 1);
}
void cal(int u, int fa, int val)
{if (num[col[u]] != 0)update(num[col[u]], -1);num[col[u]]+= val;if (num[col[u]] != 0)update(num[col[u]], 1);for (auto v : vec[u]) {if (v == fa || v == Son)continue;cal(v, u, val);}
}
void dfs2(int u, int fa, int keep)
{for (auto v : vec[u]) {if (v == fa || v == son[u])continue;dfs2(v, u, 0);}if (son[u]) {dfs2(son[u], u, 1);Son= son[u];}cal(u, fa, 1);for (auto it : q[u]) {int k= it.first;int id= it.second;ans[id]= query(k, n);}Son= 0;if (!keep) {cal(u, fa, -1);}
}
int main()
{//rd_test();read(n, m);for (int i= 1; i <= n; i++) {read(col[i]);}for (int i= 1; i < n; i++) {int u, v;read(u, v);vec[u].push_back(v);vec[v].push_back(u);}dfs(1, 0);for (int i= 1; i <= m; i++) {int v, k;read(v, k);q[v].push_back({k, i});// read(q[i].v,q[i].k);}dfs2(1, 0, 0);for (int i= 1; i <= m; i++)printf("%d\n", ans[i]);//Time_test();
}

cf375D. Tree and Queries相关推荐

  1. CF375D Tree and Queries(dsu on tree)

    题解: 个人感觉这个题目是一个挺不错的题的.(这里就不说dsu on tree的这个过程是什么了) 我们在dsu on tree计算答案时需要有一个小小技巧去优化一下时间复杂度. 就是当我们用一个cn ...

  2. cf375D. Tree and Queries(莫队)

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

  3. CodeForces 375D Tree and Queries

    传送门:https://codeforces.com/problemset/problem/375/D 题意: 给你一颗有根树,树上每个节点都有其对应的颜色,有m次询问,每次问你以点v为父节点的子树内 ...

  4. 树上启发式合并问题 ---- D. Tree and Queries[树上启发式合并+树状数组]

    题目链接 题目大意: 就是给你一棵树,树上每个节点都有一个颜色,在你mmm次询问每次询问给你一个节点uuu和一个数字kkk,问你在uuu这颗子树里面又少种颜色的结点个数是大于kkk; 解题思路: 看到 ...

  5. Codeforces 375D - Tree and Queries(dfs序+莫队)

    题目链接:http://codeforces.com/contest/351/problem/D 题目大意:n个数,col[i]对应第i个数的颜色,并给你他们之间的树形关系(以1为根),有m次询问,每 ...

  6. CF 375D. Tree and Queries加强版!!!【dfs序分块 大小分类讨论】

    传送门 题意: 一棵树,询问一个子树内出现次数$\ge k$的颜色有几种,Candy?这个沙茶自带强制在线 吐槽: 本来一道可以离散的莫队我非要强制在线用分块做:上午就开始写了然后发现思路错了...: ...

  7. CodeForces - 375D Tree and Queries(树上启发式合并)

    题目链接:点击查看 题目大意:给出一棵有根树,每个节点都有一个编号代表颜色,现在给出m个询问,每个询问的形式为u k,需要回答以u为根节点的子树中,数量超过k的颜色有多少种 题目分析:树上启发式合并模 ...

  8. CodeForces - 375D Tree and Queries 树启 + 思维

    传送门 题意: 思路: 很明显子树问题会想到树启,让后如何updateupdateupdate呢?一个显然的思路就是维护一个树状数组,查询次数>=kj>=k_j>=kj​的个数.但是 ...

  9. Codeforces Round #316 (Div. 2) D. Tree Requests dfs序

    题目链接: 题目 D. Tree Requests time limit per test:2 seconds memory limit per test:256 megabytes 问题描述 Rom ...

最新文章

  1. 自顶向下 与自底向上解决01 背包问题
  2. VSCode自定义代码片段10—— 数组的响应式方法
  3. 2016年上半年数据库系统工程师上午真题
  4. COJ 0967 WZJ的数据结构(负三十三)
  5. 软件项目估算是一件很难的事情
  6. 全国二级c语言公共基础知识,全国计算机二级C语言及公共基础知识复习资料
  7. 智慧工地解决方案施工升降机智能监控系统
  8. jmeter的脚本录制3
  9. MariaDB数据库导出导入
  10. Python自动化完成tb喵币任务
  11. Android 中编写一个简易购物车,商品包括商品名称,单价,数量,可以对商品进行增删改查功能。(ArrayList,SQLite)
  12. 西门子博图功能指令——标准化
  13. android 桌面动画,Android 如何在Launcher的桌面滑动时添加动画效果? M
  14. 15 款精致mac应用
  15. ElasticSearch 7.x 入门与实战
  16. TCP/UDP协议常用端口号服务
  17. 刘慈欣 计算机工程师,刘慈欣为什么这么厉害 科幻作家刘慈欣作品有哪些
  18. C语言经典例题100道(辗转相除求最大公约数和最小公倍数)
  19. 沃弗永磁:从结构角度来对分析为什么限矩型永磁偶合器替代限矩型液力偶合器已经成为趋势
  20. 检测、获取控制硬件摄像头,扬声器,麦克风的C#小实例

热门文章

  1. 10岁吊打职业教师的天才,仅用10篇论文称霸数学界160多年,40岁英年早逝却迄今无人超越...
  2. 看到这块Google的“墓地”,心中作何感想?| 今日最佳
  3. 据说这是史上最牛逼的可视化神器
  4. 数学告诉你家庭关系的奥秘
  5. hadoop安装hive及配置mysql_Hadoop系列之Hive(数据仓库)安装配置
  6. ubuntu linux 批量部署,使用Cobbler批量部署Linux和Windows:CentOS/Ubuntu批量安装(二)...
  7. java 图片压缩 base64_图片改变像素,宽高,Base64编码处理
  8. linux ubuntu 开启ssh服务,开启SSH服务远程登录ubuntu
  9. 链接服务器 慢_redis服务器cpu100%的原因和解决方案
  10. 群同态基本定理证明_群论(7): 群代数, 群表示基础