首页 > 其他分享 >Dsu on tree

Dsu on tree

时间:2022-08-18 09:13:08浏览次数:90  
标签:cot int sum Dsu tree son fa &&

Dsu on tree 代指树上启发式合并,并非是并查集个人觉得这个算法的思想跟莫队有些许相似,但是又利用了树链剖分的一些性质,从而使得复杂度大大降低,优秀的o(nlgn)

需要的前置技能:链式前向星,树链剖分。

U41492 树上数颜色

给出一棵结点有不同颜色的数,询问某个子树有多少种不同的颜色?

传送门
思考一下最暴力的做法,对于每个结点都开一个cnt数组,记录自己的颜色,然后往上合并,处理完以后提供查询,显然空间得炸!

我们可以很显然的看到,一个节点是由它的子节点的合并而来,那么如果我们使用一个数组,去记录某个儿子,然后记录到答案以后再清空,再给下一个儿子使用,这样可以吗?显然是可以的,但是时间复杂度就不允许了?怎么办?
树链剖分的性质:一个点到根路径上不超过log条轻边,等价于一个点最多会被暴力合并logn次

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int cnt, head[N];
struct E
{
    int to, nex;
} e[N << 1];
inline void add_edge(int u, int v)
{
    e[++cnt].to = v, e[cnt].nex = head[u], head[u] = cnt;
}
int siz[N], son[N];
void dfs(int u, int fa)
{
    siz[u] = 1;
    for(int i = head[u]; i; i = e[i].nex)
    {
        int v = e[i].to;
        if(v == fa) continue;
        dfs(v, u);
        siz[u] += siz[v];
        if(siz[v] > siz[son[u]]) son[u] = v;
    }
}
int a[N], ok[N], cot[N], sum;
void cal(int u, int fa, int val)
{
    cot[a[u]] += val;
    if(val == 1 && cot[a[u]] == 1) sum++;
    if(val == -1 && cot[a[u]] == 0) sum--;
    for(int i = head[u]; i; i = e[i].nex)
    {
        int v = e[i].to;
        if(v != fa) cal(v, u, val);
    }
}
void dsu(int u, int fa, bool flag)
{
    for(int i = head[u]; i; i = e[i].nex)
    {
        int v = e[i].to;
        if(v != fa && v != son[u]) dsu(v, u, true);
    }
    if(son[u] != 0) dsu(son[u], u, false);
    cot[a[u]]++;
    if(cot[a[u]] == 1) sum++;
    for(int i = head[u]; i; i = e[i].nex)
    {
        int v = e[i].to;
        if(v != fa && v != son[u]) cal(v, u, 1);
    }
    ok[u] = sum;
    if(flag) cal(u, fa, -1);
}
int n, m;
signed main()
{
    ios::sync_with_stdio(false), cin.tie(0);
    cin >> n;
    for(int i = 1, u, v; i < n; ++i)
    {
        cin >> u >> v;
        add_edge(u, v), add_edge(v, u);
    }
    for(int i = 1; i <= n; ++i) cin >> a[i];
    dfs(1, 0);
    dsu(1, 0, 0);
    cin >> m;
    int x;
    while(m-- && cin >> x) cout << ok[x] << "\n";
    return 0;
}

标签:cot,int,sum,Dsu,tree,son,fa,&&
From: https://www.cnblogs.com/-ytz/p/16597513.html

相关文章

  • AVL Tree (1) - Definition, find and Rotation
    1.定义(15-1)[AVLtree]:一棵空二叉树是AVLtree;若T是一棵非空二叉树,则T满足以下两个条件时,T是一棵AVLtree:T_LeftSubtree和T_RightSubtree是AV......
  • binary search tree(bst)
    什么是bst?bst树,通常称为二叉搜索树,又叫二叉排序树,bst是一种特殊的二叉树结构,也是一种常见的数据结构类型,其中,bst很明显的特性是根节点大于左子树的节点小于右子树的节点,......
  • CF715C Digit Tree
    沝黑。首先这种统计路径的问题一般联想点分治,然后考虑如何处理经过一个点\(u\)的路径。考虑有一个点\(p\inu\)的子树,然后记录路径\(p\tou\)和路径\(u\top\)的......
  • Balanced Tree (数学函数式子的处理)
    题目大意•求n个点组成的每个节点都满足左右子树大小相差至多1的二叉树个数.•0≤n<264.•关键词:计数2022-暑假-VirtualJudge(vjudge.net)思路:直接用......
  • The following untracked working tree files would be overwritten by checkout
    当使用gitcheckout[branchname]进行分支切换的时候,报了异常:error:Thefollowinguntrackedworkingtreefileswouldbeoverwrittenbycheckout:好多网上推荐......
  • luoguP3521 [POI2011]ROT-Tree Rotations【线段树】
    你要写热,就不能只写热。要写酷暑,写骄阳,写他人耳闻便生恐的炙烤和炎灼。要写白日出门一刻便肤色黝黑,背心透彻。写求雨心切,写出行伞遮。写夜晚不停的风扇和蝉聒。写鸡......
  • K-D Tree
    \(k-DTree\)是一种可以高效处理\(k\)维空间信息的数据结构。在结点数远大于\(k\)时,应用\(k-DTree\)的时间效率很好。——OIWiki对于建树,主流写法是平衡树......
  • hdu7215 Weighted Beautiful Tree
    problem一个点的点权的可能为不变或者变为连着的边的边权。然后dp、dp[u][0]表示变成大于等于w[u]边的最小代价。dp[u][1]表示变成小于等于w[u]边的最小代价。然后对......
  • P2619 [国家集训队]Tree I(K 度限制生成树 二分)
    P2619[国家集训队]TreeI一张\(n\)个点\(m\)条边的带权无向联通图,每条边是黑色或白色。求一棵最小权的恰好有\(need\)条白色边的生成树,题目保证有解。\(n\le5\t......
  • [atAGC025E]Walking on a Tree
    设第$i$条边被$c_{i}$条路径覆盖,显然答案上界为$\sum\min(c_{i},2)$事实上,上界可以被取到,考虑以下构造——取树上的一个叶子,假设其到父亲的边为$i$,对其分类讨论:1.若$c_{......