• bzoj 4196:[NOI2015] 软件包管理器 (树链剖分)


    第一次做树剖

    找同学要了模板 + 各种借鉴

    先用dfs在划分轻重链并编号, install的时候就从查询的节点到根寻找标记的点有多少个,再用深度减去标记的点的个数,并把路径上所有点都标记

    uninstall就是搜索查询的点的子树的标记个数,并取消所有的标记。

    代码如下

      1 /**************************************************************
      2     Problem: 4196
      3     Language: C++
      4     Result: Accepted
      5     Time:8312 ms
      6     Memory:7416 kb
      7 ****************************************************************/
      8  
      9 #include <cstdio>
     10 #include <vector>
     11 #include <cstring>
     12 using namespace std;
     13 #define g(l, r) (l + r | l != r)
     14 #define o g(l, r)
     15 #define ls g(l, mid)
     16 #define rs g(mid + 1, r)
     17 const int N = 100100; 
     18  
     19 int n, dep[N], fa[N], hs[N], size[N], top[N], pos[N], mark[N<<1], sum[N<<1], tot, L, R, m;
     20 vector < int > edge[N];
     21  
     22 inline void dfs1(int u, int d, int f){
     23     dep[u] = d; fa[u] = f;  hs[u] = -1;  size[u] = 1;
     24     int tmp = 0;
     25     for (int i = 0; i < edge[u].size(); i++){
     26         int &v = edge[u][i];
     27         dfs1(v, d + 1, u);
     28         if (size[v] > tmp)
     29             hs[u] = v, tmp = size[v];
     30         size[u] += size[v];
     31     }
     32 }
     33  
     34 inline void dfs2(int u, int T){
     35     top[u] = T; pos[u] = ++tot;
     36     if (hs[u] == -1)    return ;
     37     dfs2(hs[u], T);
     38     for (int i = 0; i < edge[u].size(); i++){
     39         int &v = edge[u][i];
     40         if (hs[u] == v) continue;
     41         dfs2(v, v);
     42     }
     43 }
     44  
     45 inline void push(int l, int r) {
     46     if (mark[o] == -1) return;
     47     int mid = l + r >> 1;
     48     if (l < r) {
     49         mark[ls] = mark[o];
     50         sum[ls] = mark[o] * (mid - l  + 1);
     51         mark[rs] = mark[o];
     52         sum[rs] = mark[o] * (r - (mid + 1) + 1);
     53     }
     54     mark[o] = -1;
     55 }
     56  
     57 void modify(int l, int r){
     58     if (L <= l && r <= R){
     59         sum[o] = m * (r - l + 1);
     60         mark[o] = m;
     61         return ;
     62     }
     63     push(l, r);
     64     int mid = l + r >> 1;
     65     if (L <= mid)    modify(l, mid);
     66     if (R >= mid + 1)    modify(mid + 1, r);
     67     sum[o] = sum[ls] + sum[rs];
     68 }
     69  
     70 int getSum(int l, int r){
     71     if (L <= l && r <= R){
     72         return sum[o];
     73     }
     74     push(l, r);
     75     int mid = l + r >> 1, ans = 0;
     76     if (L <= mid)    ans += getSum(l, mid);
     77     if (R >= mid + 1)    ans += getSum(mid + 1, r);
     78     return ans;
     79 }
     80  
     81 inline void install(int u){
     82     int f = top[u], ans = dep[u];
     83     m = 1;
     84     while(f){
     85         L = pos[f], R = pos[u];
     86         ans -= getSum(1, tot);
     87         modify(1, tot);
     88         u = fa[f]; f = top[u];
     89     }
     90     L = pos[f], R = pos[u];
     91     ans -= getSum(1, tot);
     92     modify(1, tot);
     93     printf("%d
    ", ans);
     94 }
     95  
     96 inline void uninstall(int u){
     97     L = pos[u], R = pos[u] + size[u] - 1, m = 0; 
     98     int ans = getSum(1, tot);
     99     modify(1, tot);
    100     printf("%d
    ", ans);
    101 }
    102  
    103 int main(){
    104     scanf("%d", &n);
    105     for (int i = 1; i < n; i++){
    106         int x; scanf("%d", &x);
    107         edge[x].push_back(i);
    108     }
    109     dfs1(0, 1, -1);  dfs2(0, 0);
    110     int q;
    111     scanf("%d", &q);
    112     memset(mark, 0xff, sizeof(mark));
    113     while(q--){
    114         char str[15]; int x;
    115         scanf("%s%d", str, &x);
    116         if (*str == 'i')    install(x);
    117         else uninstall(x);
    118     }
    119     return 0;
    120 } 
  • 相关阅读:
    图像 resize 代码:保留 aspect ratio(长宽比)
    Pytorch lr_scheduler 中的 last_epoch 用法
    torch.optim用法(参数组的设置)
    课程式学习(Curriculum Learning)
    扇贝单词本-隐藏中文释义 tampermonkey
    电话号码正向标记认证网站申请地址
    考研英语做题计时器网页版(每隔3分钟播放声音,提醒计时)
    mac关闭自动更新后还在每天提醒进行安装更新
    mac 自动生成自签证书脚本
    Ditto
  • 原文地址:https://www.cnblogs.com/cminus/p/7044023.html
Copyright © 2020-2023  润新知