zoukankan      html  css  js  c++  java
  • Luogu 4556 雨天的尾巴

    Solution

    用$col$记录 数量最多的种类, $sum$记录 种类$col$ 的数量。

    然后问题就是树上链修改, 求 每个节点 数量最多的种类。

    用树上差分 + 线段树合并更新即可。

    Code

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define rd read()
      5 using namespace std;
      6 
      7 const int N = 1e5 + 5;
      8 
      9 int head[N], cnt;
     10 int n, m;
     11 int sum[N], top[N], son[N], sz[N], f[N], dep[N];
     12 int u[N], v[N], z[N], b[N], tot, ans[N], idf[N];
     13 
     14 struct edge {
     15     int nxt, to;
     16 }e[N << 1];
     17 
     18 int read() {
     19     int X = 0, p = 1; char c = getchar();
     20     for (; c > '9' || c < '0'; c = getchar()) 
     21         if (c == '-') p = -1;
     22     for (; c >= '0' && c <= '9'; c = getchar())
     23         X = X * 10 + c - '0';
     24     return X * p;
     25 }
     26 
     27 void add(int u, int v) {
     28     e[++cnt].to = v;
     29     e[cnt].nxt = head[u];
     30     head[u] = cnt;
     31 }
     32 
     33 int fd(int x) {
     34     return lower_bound(b + 1, b + 1 + tot, x) - b;
     35 }
     36 
     37 namespace SegT {
     38 
     39     struct node {
     40         int sum, col, lson, rson;
     41         node() {
     42             sum = col = lson = rson = 0;
     43         }
     44     } s[N * 50];
     45 
     46     int root[N];
     47 
     48 #define lc(p) s[p].lson
     49 #define rc(p) s[p].rson
     50 #define sum(p) s[p].sum
     51 #define col(p) s[p].col
     52 #define mid ((l + r) >> 1)
     53 
     54     int st[N * 50], tp, qnum;
     55 
     56     int get() {
     57         if (tp) {
     58             int re = st[tp];
     59             tp--;
     60             return re;
     61         }
     62             
     63         else return ++qnum;
     64     }
     65 
     66     void del(int x) {
     67         lc(x) = rc(x) = sum(x) =  col(x) = 0;
     68         st[++tp] = x;
     69     }
     70 
     71     void up(int p) {
     72         if(sum(lc(p)) >= sum(rc(p)))
     73             sum(p) = sum(lc(p)), col(p) = col(lc(p));
     74         else 
     75             sum(p) = sum(rc(p)), col(p) = col(rc(p));
     76     }
     77 
     78     void modify(int l, int r, int pos, int d, int &x) {
     79         if(!x) x = get();
     80         if (l == r) {
     81             sum(x) += d;
     82             if (sum(x) > 0) 
     83                 col(x) = pos;
     84             return;
     85         }
     86         if (pos <= mid)
     87             modify(l, mid, pos, d, lc(x));
     88         else 
     89             modify(mid + 1, r, pos, d, rc(x));
     90         up(x);
     91     }
     92 
     93     int merge(int l, int r, int x, int y) {
     94         if (!x || !y)
     95             return x + y;
     96         int now = get();
     97         if (l == r) {
     98             sum(now) = sum(x) + sum(y);
     99             if (sum(now) > 0)
    100                 col(now) = max(col(x), col(y));
    101             else col(now) = 0;
    102         }
    103         else {
    104             lc(now) = merge(l, mid, lc(x), lc(y));
    105             rc(now) = merge(mid + 1, r, rc(x), rc(y));
    106             up(now);
    107         }
    108         del(x); del(y);
    109         return now;
    110     }
    111 }
    112 
    113 using namespace SegT;
    114 
    115 namespace SP {
    116     void dfs1(int x) {
    117         sz[x] = 1;
    118         for (int i = head[x]; i; i = e[i].nxt) {
    119             int nt = e[i].to;
    120             if (nt == f[x])
    121                 continue;
    122             f[nt] = x;
    123             dep[nt] = dep[x] + 1;
    124             SP::dfs1(nt);
    125             sz[x] += sz[nt];
    126             if (sz[nt] > sz[son[x]])
    127                 son[x] = nt;
    128         }
    129     }
    130 
    131     void dfs2(int x) {
    132         if (!son[x])
    133             return;
    134         top[son[x]] = top[x];
    135         SP::dfs2(son[x]);
    136         for (int i = head[x]; i; i = e[i].nxt) {
    137             int nt = e[i].to;
    138             if (nt == f[x] || nt == son[x])
    139                 continue;
    140             top[nt] = nt;
    141             SP::dfs2(nt);
    142         }
    143     }
    144 
    145     int LCA(int x, int y) {
    146         for (; top[x] != top[y];) {
    147             if (dep[top[x]] < dep[top[y]])
    148                 swap(x, y);
    149             x = f[top[x]];
    150         }
    151         if (dep[x] < dep[y])
    152             swap(x, y);
    153         return y;
    154     }
    155 
    156     void solve(int x) {
    157         for (int i = head[x]; i; i = e[i].nxt) {
    158             int nt = e[i].to;
    159             if (nt == f[x])
    160                 continue;
    161             SP::solve(nt);
    162             root[x] = merge(1, tot, root[x], root[nt]);
    163         }
    164         ans[x] = col(root[x]);
    165     }
    166 }
    167 
    168 int main()
    169 {
    170     n = rd; m = rd;
    171     for (int i = 1; i < n; ++i) {
    172         int x = rd, y = rd;
    173         add(x, y); add(y, x);
    174     }
    175     dep[1] = 1;
    176     SP::dfs1(1);
    177     top[1] = 1;
    178     SP::dfs2(1);
    179     for (int i = 1; i <= m; ++i) {
    180         u[i] = rd; v[i] = rd;
    181         z[i] = b[i] = rd;
    182     }
    183     tot = m;
    184     sort(b + 1, b + 1 + tot);
    185     tot = unique(b + 1, b + 1 + tot) - b - 1;
    186     for (int i = 1; i <= tot; ++i)
    187         idf[b[i]] = i;
    188     for (int i = 1; i <= m; ++i) {
    189         int lca = SP::LCA(u[i], v[i]);
    190         modify(1, tot, idf[z[i]], 1, root[u[i]]);
    191         modify(1, tot, idf[z[i]], 1, root[v[i]]);
    192         modify(1, tot, idf[z[i]], -1, root[lca]);
    193         modify(1, tot, idf[z[i]], -1, root[f[lca]]);
    194     }
    195     SP::solve(1);
    196     for (int i = 1; i <= n; ++i)
    197         printf("%d
    " ,b[ans[i]]);
    198 }
    View Code
  • 相关阅读:
    装饰器wraps
    装饰器的语法糖
    VisionPro 自学帮助
    准备重新编译VisionPro 官方版本 使用 vs2019
    个人随笔_学习感悟
    VisionPro 一些图操作
    System.Data.Sqlite.dll 使用异常问题参考
    NOPI笔记01
    VisionPro帮助文档学习01(UserGuide DisPlay)
    MSSqlServer基础学习01
  • 原文地址:https://www.cnblogs.com/cychester/p/9679854.html
Copyright © 2011-2022 走看看