zoukankan      html  css  js  c++  java
  • Dsu on tree算法

    树上启发式合并,一个O(nlogn)处理树上查询问题比较好的算法(不能修改)。

    codeforces600E

    题意:一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和。

    codeforces570D

    题目大意:

    给定一个以1为根的n个节点的树,每个点上有一个字母(a-z),

    每个点的深度定义为该节点到1号节点路径上的点数.

    每次询问 a,b.查询以a为根的子树内深度为b的节点上的字母重新排列之后是否能构成回文串.

    codeforces208E

    题目大意:给你一片森林,每次询问一个点与多少个点拥有共同的K级祖先

    codeforces246E

    给定一片森林,每次询问一个节点的K-Son共有个多少不同的名字。

    一个节点的K-Son即为深度是该节点深度加K的节点。

    codeforces1009F

    给定一棵以 1 为根,n 个节点的树。设 d(u,x)为 u 子树中到 u 距离为 x 的节点数。

    对于每个点,求一个最小的 k,使得 d(u,k) 最大。

    codeforces375D

    题目大意:给出一棵 n 个结点的树,每个结点有一个颜色 c i 。 询问 q 次,每次询问以 v 结点为根的子树中,出现次数 ≥k 的颜色有多少种。树的根节点是1。

    codeforeces741D

    一棵根为1 的树,每条边上有一个字符(a-v共22种)。

    一条简单路径被称为Dokhtar-kosh当且仅当路径上的字符经过重新排序后可以变成一个回文串。 求每个子树中最长的Dokhtar-kosh路径的长度。

    2019ICPC南昌K题

    给定一颗树,求有多少个点对(x,y)满足:(1)二者不在一条链上(2)val[x]+val[y] = 2*val[lca(x,y)](3)二者之间的距离 <= k

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int N = 1e5 + 10;
      5 int n, k;
      6 vector<int>g[N];
      7 struct seg{
      8     int l, r;
      9     int sum;
     10 }tr[N * 100];
     11 int size[N], son[N], Son, d[N];
     12 int tot, root[N];
     13 int val[N];
     14 ll ans;
     15 void insert(int &rt, int l, int r, int pos, int x)
     16 {
     17     if(!rt) rt = ++ tot;
     18     tr[rt].sum += x;
     19     if(l == r) return ;
     20     int mid = l + r >> 1;
     21     if(pos <= mid) insert(tr[rt].l, l, mid, pos, x);
     22     else insert(tr[rt].r, mid + 1, r, pos, x);
     23 }
     24 
     25 int query(int rt, int l, int r, int L, int R)
     26 {
     27     if(!rt) return 0;
     28     if(L <= l && R >= r) return tr[rt].sum;
     29     int res = 0;;
     30     int mid = l + r >> 1;
     31     if(L <= mid) res += query(tr[rt].l, l, mid, L, R);
     32     if(R > mid ) res += query(tr[rt].r, mid + 1, r, L, R);
     33     return res;
     34 }
     35 
     36 void dfs(int u, int fa)
     37 {
     38 //    cout << u << " " << fa << '
    ';
     39     d[u] = d[fa] + 1;
     40     size[u] = 1;
     41     for (auto &j : g[u])
     42     {
     43         if(j == fa) continue;
     44         dfs(j, u);
     45         size[u] += size[j];
     46         if(size[son[u]] < size[j])
     47             son[u] = j;
     48     }
     49 }
     50 
     51 
     52 void  calans(int u, int td, int tv)
     53 {
     54     int dd = k + 2 * td - d[u];
     55     dd = min(dd, n);
     56     int t = 2 * tv - val[u];
     57     if(dd >= 1 && t >= 0 && t <= n)
     58         ans = ans + 1ll * query(root[t], 1, n, 1, dd);
     59     for (auto &j : g[u])
     60         calans(j, td, tv);
     61 }
     62 
     63 void add(int u, int x)
     64 {
     65     int t = val[u];
     66     insert(root[t], 1, n, d[u], x);
     67     for (auto &j : g[u])
     68         add(j,x);
     69 }
     70 
     71 
     72 void dsu(int u, int opt)
     73 {
     74     for (auto &j : g[u])
     75     {
     76         if(j == son[u]) continue;
     77         dsu(j, 0);
     78     }
     79     if(son[u]) dsu(son[u], 1), Son = son[u];
     80     for (auto &j : g[u])
     81     {
     82         if(j == son[u]) continue;
     83         calans(j, d[u], val[u]);
     84         add(j, 1);
     85     }
     86     insert(root[val[u]], 1, n, d[u], 1);
     87     if(!opt) add(u, -1);
     88 }
     89 
     90 int main()
     91 {
     92     scanf("%d%d", &n, &k);
     93     for (int i = 1; i <= n; i ++)    scanf("%d", &val[i]);
     94     for (int i = 2; i <= n; i ++) 
     95     {
     96         int x;
     97         scanf("%d", &x);
     98         g[x].push_back(i);
     99     }
    100     dfs(1, 0);
    101     dsu(1, 0);
    102     printf("%lld
    ", ans * 2 );
    103 }
    View Code
  • 相关阅读:
    uvm_misc——杂货铺(miscellaneous)
    23种设计模式及其应用场景
    Hadoop TextInputFormat源码分析
    java字符串替换函数高效实现
    hadoop HA 之 QJM
    中文分词词性对照表
    计算两个字符串编辑距离
    java 图片处理
    zookeeper数据迁移
    正则表达式
  • 原文地址:https://www.cnblogs.com/xwdzuishuai/p/13198903.html
Copyright © 2011-2022 走看看