• [luoguP2146] 软件包管理器(树链剖分)


    传送门

    看着很吓人,其实就是个树链剖分模板。

    可支持操作:

    1.将节点 x 到 根 的路径上的值都变成 1 

    2.将以节点 x 为根的子树的值都变成 0

    1A爽~

    ——代码

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <iostream>
      5 #define root 1, 1, n
      6 #define ls now << 1, l, mid
      7 #define rs now << 1 | 1, mid + 1, r
      8 
      9 const int MAXN = 1000001;
     10 int n, m, cnt, tim, ans;
     11 int head[MAXN], to[MAXN], next[MAXN];
     12 int f[MAXN], son[MAXN], size[MAXN], deep[MAXN], tid[MAXN], top[MAXN], sum[MAXN << 2], turn[MAXN << 2];
     13 
     14 inline int read()
     15 {
     16     int f = 1, x = 0;
     17     char ch = getchar();
     18     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
     19     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
     20     return x * f;
     21 }
     22 
     23 inline void add(int x, int y)
     24 {
     25     to[cnt] = y;
     26     next[cnt] = head[x];
     27     head[x] = cnt++;
     28 }
     29 
     30 inline void dfs1(int u)
     31 {
     32     int i, v;
     33     size[u] = 1;
     34     deep[u] = deep[f[u]] + 1;
     35     for(i = head[u]; i != -1; i = next[i])
     36     {
     37         v = to[i];
     38         dfs1(v);
     39         size[u] += size[v];
     40         if(son[u] == -1 || size[son[u]] < size[v]) son[u] = v;
     41     }
     42 }
     43 
     44 inline void dfs2(int u, int tp)
     45 {
     46     int i, v;
     47     top[u] = tp;
     48     tid[u] = ++tim;
     49     if(son[u] != -1) dfs2(son[u], tp);
     50     for(i = head[u]; i != -1; i = next[i])
     51     {
     52         v = to[i];
     53         if(v != son[u]) dfs2(v, v);
     54     }
     55 }
     56 
     57 inline void swap(int &x, int &y)
     58 {
     59     x ^= y ^= x ^= y;
     60 }
     61 
     62 inline void pushup(int now)
     63 {
     64     sum[now] = sum[now << 1] + sum[now << 1 | 1];
     65 }
     66 
     67 inline void pushdown(int now, int len)
     68 {
     69     if(turn[now] == -1) return;
     70     sum[now << 1] = turn[now] * (len - (len >> 1));
     71     sum[now << 1 | 1] = turn[now] * (len >> 1);
     72     turn[now << 1] = turn[now];
     73     turn[now << 1 | 1] = turn[now];
     74     turn[now] = -1;
     75 }
     76 
     77 inline void update(int x, int ql, int qr, int now, int l, int r)
     78 {
     79     if(ql <= l && r <= qr)
     80     {
     81         ans += std::abs(x * (r - l + 1) - sum[now]);
     82         sum[now] = (r - l + 1) * x;
     83         turn[now] = x;
     84         return;
     85     }
     86     if(r < ql || l > qr) return;
     87     pushdown(now, r - l + 1);
     88     int mid = (l + r) >> 1;
     89     update(x, ql, qr, ls);
     90     update(x, ql, qr, rs);
     91     pushup(now);
     92 }
     93 
     94 inline void qupdate(int x, int u, int v)
     95 {
     96     while(top[u] != top[v])
     97     {
     98         if(deep[top[u]] < deep[top[v]]) swap(u, v);
     99         update(x, tid[top[u]], tid[u], root);
    100         u = f[top[u]];
    101     }
    102     if(deep[u] > deep[v]) swap(u, v);
    103     update(x, tid[u], tid[v], root);
    104 }
    105 
    106 int main()
    107 {
    108     int i, x;
    109     char s[10];
    110     n = read();
    111     memset(son, -1, sizeof(son));
    112     memset(head, -1, sizeof(head));
    113     memset(turn, -1, sizeof(turn));
    114     for(i = 1; i < n; i++)
    115     {
    116         x = read();
    117         f[i] = x;
    118         add(x, i);
    119     }
    120     dfs1(0);
    121     dfs2(0, 0);
    122     m = read();
    123     for(i = 1; i <= m; i++)
    124     {
    125         scanf("%s", s);
    126         x = read();
    127         ans = 0;
    128         if(s[0] == 'i') qupdate(1, 0, x);
    129         else update(0, tid[x], tid[x] + size[x] - 1, root);
    130         printf("%d
    ", ans);
    131     }
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    优化Hibernate所鼓励的7大措施:
    Java未赋值变量的默认初始值
    年轻代
    JVM介绍
    Java锁的种类以及辨析
    java语言复制数组的四种方法
    static和final
    抽象函数抽象类
    try catch finally
    九大内置对象
  • 原文地址:https://www.cnblogs.com/zhenghaotian/p/6855000.html
Copyright © 2020-2023  润新知