zoukankan      html  css  js  c++  java
  • [NOI2015]软件包管理器

    嘟嘟嘟

    这明显就是一道树剖的水题~~~

    install操作就是查询x到根节点的路径中0的个数,并且每一个节点的权值都改成1.

    uninstall就是查询x的子树中1的个数,并都改成0.

    有一个优化就是install操作中如果当前区间已经有1了,就可以不用往上查,直接返回。因为从题中可以得到一个信息,如果有一个点的权值是1,那么他祖先的所有节点一定都是1。

    嗯,完了。

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("") 
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 1e5 + 5;
     21 inline ll read()
     22 {
     23     ll ans = 0;
     24     char ch = getchar(), last = ' ';
     25     while(!isdigit(ch)) {last = ch; ch = getchar();}
     26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
     27     if(last == '-') ans = -ans;
     28     return ans;
     29 }
     30 inline void write(ll x)
     31 {
     32     if(x < 0) x = -x, putchar('-');
     33     if(x >= 10) write(x / 10);
     34     putchar(x % 10 + '0');
     35 }
     36 
     37 int n, m;
     38 vector<int> v[maxn];
     39 
     40 int dep[maxn], fa[maxn], siz[maxn], son[maxn];
     41 void dfs1(int now)
     42 {
     43     siz[now] = 1;
     44     for(int i = 0; i < (int)v[now].size(); ++i)
     45     {
     46         dep[v[now][i]] = dep[now] + 1;
     47         fa[v[now][i]] = now;
     48         dfs1(v[now][i]);
     49         siz[now] += siz[v[now][i]];
     50         if(!son[now] || siz[son[now]] < siz[v[now][i]]) son[now] = v[now][i];
     51     }
     52 }
     53 int dfsx[maxn], pos[maxn], top[maxn], cnt = 0;
     54 void dfs2(int now)
     55 {
     56     dfsx[now] = ++cnt; pos[cnt] = now;
     57     if(son[now])
     58     {
     59         top[son[now]] = top[now];
     60         dfs2(son[now]);
     61     }
     62     for(int i = 0; i < (int)v[now].size(); ++i)
     63     {
     64         if(v[now][i] != son[now])
     65         {
     66             top[v[now][i]] = v[now][i];
     67             dfs2(v[now][i]);
     68         }
     69     }
     70 }
     71 
     72 int l[maxn << 2], r[maxn << 2], sum[maxn << 2], lzy[maxn << 2];
     73 void build(int L, int R, int now)
     74 {
     75     l[now] = L; r[now] = R;
     76     lzy[now] = -1;
     77     if(L == R) return;
     78     int mid = (L + R) >> 1;
     79     build(L, mid, now << 1);
     80     build(mid + 1, R, now << 1 | 1);
     81 }
     82 void pushdown(int now)
     83 {
     84     if(lzy[now] != -1)
     85     {
     86         sum[now << 1] = (r[now << 1] - l[now << 1] + 1) * lzy[now];
     87         sum[now << 1 | 1] = (r[now << 1 | 1] - l[now << 1 | 1] + 1) * lzy[now];
     88         lzy[now << 1] = lzy[now << 1 | 1] = lzy[now];
     89         lzy[now] = -1;
     90     }
     91 }
     92 void update(int L, int R, int now, bool flg)
     93 {
     94     if(L == l[now] && R == r[now]) 
     95     {
     96         sum[now] = (R - L + 1) * flg;
     97         lzy[now] = flg; return;
     98     }
     99     pushdown(now);
    100     int mid = (l[now] + r[now]) >> 1;
    101     if(R <= mid) update(L, R, now << 1, flg);
    102     else if(L > mid) update(L, R, now << 1 | 1, flg);
    103     else update(L, mid, now << 1, flg), update(mid + 1, R, now << 1 | 1, flg);
    104     sum[now] = sum[now << 1] + sum[now << 1 | 1]; 
    105 }
    106 int query(int L, int R, int now)
    107 {
    108     if(L == l[now] && R == r[now]) return sum[now];
    109     pushdown(now);
    110     int mid = (l[now] + r[now]) >> 1;
    111     if(R <= mid) return query(L, R, now << 1);
    112     else if(L > mid) return query(L, R, now << 1 | 1);
    113     else return query(L, mid, now << 1) + query(mid + 1, R, now << 1 | 1);
    114 }
    115 
    116 int query_in(int x)
    117 {
    118     int ret = 0;
    119     bool flg = 1;
    120     while(top[x] != top[1])
    121     {
    122         int tp = query(dfsx[top[x]], dfsx[x], 1);
    123         ret += dfsx[x] - dfsx[top[x]] + 1 - tp;
    124         update(dfsx[top[x]], dfsx[x], 1, 1);
    125         if(tp) {flg = 0; break;}
    126         x = fa[top[x]];
    127     }
    128     if(!flg) return ret;
    129     ret += dfsx[x] - dfsx[1] + 1 - query(dfsx[1], dfsx[x], 1);
    130     update(dfsx[1], dfsx[x], 1, 1);
    131     return ret;
    132 }
    133 int query_un(int x)
    134 {
    135     int ret = query(dfsx[x], dfsx[x] + siz[x] - 1, 1);
    136     update(dfsx[x], dfsx[x] + siz[x] - 1, 1, 0);
    137     return ret;
    138 }
    139 
    140 char c[12];
    141 
    142 int main()
    143 {
    144     n = read();
    145     for(int i = 2; i <= n; ++i) 
    146     {
    147         int x = read() + 1;
    148         v[x].push_back(i);
    149     }
    150     dfs1(1); top[1] = 1; dfs2(1);
    151     build(1, cnt, 1);
    152     m = read();
    153     for(int i = 1; i <= m; ++i)
    154     {
    155         scanf("%s", c); int x = read() + 1;
    156         if(c[0] == 'i') write(query_in(x)), enter;
    157         else write(query_un(x)), enter;
    158     }
    159     return 0;
    160 }
    View Code
  • 相关阅读:
    JS基础知识点2
    JS基础知识
    CSS-弹性盒子
    css取值
    css语法和规则
    第7-9章作业汇总
    第7-9章作业---第3题
    第四次作业——第一题
    第四次作业-第二题
    第四次作业---第四题
  • 原文地址:https://www.cnblogs.com/mrclr/p/9700094.html
Copyright © 2011-2022 走看看