首页 > 其他分享 >P9233 [蓝桥杯 2023 省 A] 颜色平衡树 (dfs序 莫队)

P9233 [蓝桥杯 2023 省 A] 颜色平衡树 (dfs序 莫队)

时间:2023-10-13 20:26:56浏览次数:33  
标签:cnt tot int sum P9233 蓝桥 ++ dfs --

P9233 [蓝桥杯 2023 省 A] 颜色平衡树 (dfs序 莫队)

莫队原理:https://zhuanlan.zhihu.com/p/115243708

对于树上的每个结点,按照 dfs 序打上时间戳,这样就可以把每一个结点对应的子树的答案转化为一个区间的答案。将子树询问离线下来变成 \(n\) 个区间查询。

用 \(cnt\) 数组维护颜色的出现次数,那么如果一个区间有贡献,当且仅当 \(cnt\) 数组中所有非零元素都一样,表示每种颜色的节点个数相同。用 \(sum\) 维护 \(cnt\) 中有多少种互不相同的元素,那么当 \(sum\) 等于 \(1\) 时,说明每种颜色的出现次数均相同,颜色平衡树的个数加一。

我们还需要用一个数组 \(tot\) 维护当前 \(cnt\) 中每种元素的出现次数,如果 \(tot\) 的某一个元素从 \(0\) 变为 \(1\),相当于 \(cnt\) 中多了一种元素,将 \(sum\) 加一;如果 \(tot\) 中的某一个元素从 \(1\) 变为 \(0\),相当于 \(cnt\) 数组中少了一种元素,将 \(sum\) 减一。

#include<bits/stdc++.h>

using namespace std;
const int N = 2e5 + 10;
int n, m, x, t, num, sum, ans, c[N];
int in[N], out[N], id[N], pos[N], cnt[N], tot[N];
vector<int> g[N];

struct Node {
    int l, r;
    bool operator <(const Node &t) const {
        if (pos[l] != pos[t.l]) return l < t.l;
        if (pos[l] & 1) return r < t.r;
        return r > t.r;
    }
} q[N];

void dfs(int x) {
    in[x] = ++num, id[num] = x;
    for (int y : g[x])    dfs(y);
    out[x] = num;
    q[++t] = {in[x], out[x]};
}

void add(int x) {
    if (cnt[c[x]]) {
        if (--tot[cnt[c[x]]] == 0)    sum--;
    }
    cnt[c[x]]++;
    if (++tot[cnt[c[x]]] == 1)    sum++;
}

void del(int x) {
    if (--tot[cnt[c[x]]] == 0)    sum--;
    cnt[c[x]]--;
    if (cnt[c[x]]) {
        if (++tot[cnt[c[x]]] == 1)    sum++;
    }
}

int main() {
    cin >> n;
    m = sqrt(n);
    for (int i = 1; i <= n; i++) {
        pos[i] = (i - 1) / m + 1; //分块
        cin >> c[i] >> x;
        g[x].push_back(i);
    }
    dfs(1), sort(q + 1, q + 1 + n);
    for (int l = 1, r = 0, i = 1; i <= n; i++) {
        while (l > q[i].l) add(id[--l]);
        while (r < q[i].r) add(id[++r]);
        while (l < q[i].l) del(id[l++]);
        while (r > q[i].r) del(id[r--]);
        if (sum == 1)    ans++;
    }
    cout << ans << endl;
}

标签:cnt,tot,int,sum,P9233,蓝桥,++,dfs,--
From: https://www.cnblogs.com/CTing/p/17763041.html

相关文章

  • FastDFS+Nginx - 本地搭建文件服务器同时实现在外远程访问「端口映射」 转载
    前言FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡......
  • 【LeetCode递归】括号生成,使用dfs
    括号匹配数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。示例1:输入:n=3输出:["((()))","(()())","(())()","()(())","()()()"]示例2:输入:n=1输出:["()"]提示:1<=n<=8代码与思路有效的括号组合要满足两个条件:①左右......
  • JAVA图搜索算法之DFS-BFS
    图算法DFS与BFSBFS和DFS代表对图进行遍历,即搜索的算法,搜索算法中常用的只要有两种算法:深度优先遍历(Depth-First-Search:DFS)和广度优先遍历(Breadth-First-Search:BFS)。一个图结构可以用来表示大量现实生活中的问题,比如,道路网络,计算机网络,社交网络,用户身份解析图①DFS......
  • FastDFS+Nginx,轻轻松松搭建一个本地文件服务器
    前言1.本地搭建FastDFS文件系统2.局域网测试访问FastDFS3.安装cpolar内网穿透4.配置公网访问地址5.固定公网地址6.测试访问固定二级子域名前言FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决......
  • CentOS 7.9 FastDFS 设置开机自启动
    CentOS7.9FastDFS设置开机自启动  一、前言关于 FastDFS服务的启动、停止、重启相关脚本,可以参考如下博客:https://www.cnblogs.com/miracle-luna/p/17750542.html本文主要讲解如何使用systemctl系统命令,进行启动、停止、重启、查看FastDFS状态等操作。 二、......
  • DFS 与 BFS
    简介状态:解决问题所关注的属性的集合。转移:状态之间的变化过程。搜索:处理状态转移、寻找新状态、枚举(遍历)所有状态的一种算法思想。搜索树:状态和有效转移形成的树形结构,每个状态只会被扩展一次。深度优先搜索全称为Depth-FirstSearch,简称DFS、深搜。这个算法一般采用......
  • 【大数据】HDFS
    HDFS原理基本介绍1:HDFS全称:HadoopDistributedFileSystem2:Hadoop三大组件(HDFS、MapReduce、YARN)之一3:可在多台服务器上构建集群,提供分布式数据存储能力4:NameNode:主角色,管理HDFS集群和DataNode角色5:DataNode:从角色,负责数据的存储6:SecondaryNameNode:辅助角色,协......
  • 题解 [蓝桥杯 2016 省 B] 交换瓶子
    题目链接本题解讲解环图的做法。要将一个\(1\simn\)的排列通过交换变成\(1\simn\),可以先将\(i\)向\(a_i\)连边,那么最终一定会练成若干个环(每个点只有一个出度,也只有一个入度)。假设交换在同一个环中的节点,一个环显然会变成两个环,也就是说,交换一次最多增加一个环的数量,......
  • 算法题解--蓝桥云课跳跃
    题目蓝桥云课跳跃1.看完题目先写了个二维数组,然后就真的不懂了,最后找了个大概能懂的题解,思路大概是是建立坐标,再用递归求出所有路径,找出其中最大的权值和2.遇到的问题还是没思路,而且写下面使用递归的方法时光出错,不是很熟练3.测试结果:4.收获:学习过的static终于派上了用场,......
  • FastDFS 简介
    FastDFS简介FastDFS是一款开源的分布式文件系统,功能主要包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了文件大容量存储和高性能访问的问题。FastDFS特别适合以文件为载体的在线服务,如图片、视频、文档等等服务。FastDFS作为一款轻量级分布式文件系统,版本V6.01代......