zoukankan      html  css  js  c++  java
  • 【NOI 2015】软件包管理器

    【题目链接】

              点击打开链接

    【算法】

            树链剖分,子树的DFS序也是连续的一段

            要注意细节!

    【代码】

           

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 100000
    
    struct SegmentTree {
        int l,r,sum[2],opt;    
    } tree[MAXN*3];
    
    int i,N,Q,x,num;
    int depth[MAXN+10],size[MAXN+10],son[MAXN+10],fa[MAXN+10],
        top[MAXN+10],id[MAXN+10];
    string type;
    vector<int> E[MAXN+10];
    
    template <typename T> inline void read(T &x) {
        int f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
        for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
        x *= f;
    }
    
    template <typename T> inline void write(T x) {
        if (x < 0) { putchar('-'); x = -x; }
        if (x > 9) write(x/10);
        putchar(x%10+'0');    
    }
    
    template <typename T> inline void writeln(T x) {
        write(x);
        puts("");    
    }
    
    inline void dfs1(int x) {
        int i,y;
        size[x] = 1;
        for (i = 0; i < E[x].size(); i++) {
            y = E[x][i];
            if (y != fa[x]) {
                fa[y] = x;
                depth[y] = depth[x] + 1;
                dfs1(y);
                size[x] += size[y];
                if ((size[y] > size[son[x]]) || (!son[x])) son[x] = y;
            }
        }    
    }
    
    inline void dfs2(int x,int tp) {
        int i,y;
        top[x] = tp; id[x] = ++num;
        if (son[x]) dfs2(son[x],tp);
        for (i = 0; i < E[x].size(); i++) {
            y = E[x][i];
            if ((y != fa[x]) && (y != son[x])) 
                dfs2(y,y);
        }     
    }
    
    inline void build(int index,int l,int r) {
        int mid;
        tree[index].l = l; tree[index].r = r;
        tree[index].opt = 0;
        tree[index].sum[0] = r - l + 1;
        if (l == r) return;
        mid = (l + r) >> 1;
        build(index*2,l,mid); build(index*2+1,mid+1,r);    
    }
    
    inline void pushdown(int index) {
        if (tree[index].l == tree[index].r) return;
        tree[index*2].opt = tree[index].opt;
        tree[index*2].sum[tree[index].opt] = tree[index*2].r - tree[index*2].l + 1;
        tree[index*2].sum[tree[index].opt^1] = 0;
        tree[index*2+1].opt = tree[index].opt;
        tree[index*2+1].sum[tree[index].opt] = tree[index*2+1].r - tree[index*2+1].l + 1;
        tree[index*2+1].sum[tree[index].opt^1] = 0;    
    }
    
    inline void pushup(int index) {
        tree[index].sum[0] = tree[index*2].sum[0] + tree[index*2+1].sum[0];
        tree[index].sum[1] = tree[index*2].sum[1] + tree[index*2+1].sum[1];
        if (tree[index*2].opt != tree[index*2+1].opt) {
            tree[index].opt = -1;
            return;
        }
        if ((tree[index*2].opt == -1) || (tree[index*2+1].opt == -1)) {
            tree[index].opt = -1;
            return;
        }
        tree[index].opt = tree[index*2].opt;
    }
    
    void modify(int index,int l,int r,int val) {
        int mid;
        if (tree[index].opt != -1) pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) {
            tree[index].sum[val] = r - l + 1;
            tree[index].sum[val^1] = 0;
            tree[index].opt = val;
        } else {
            mid = (tree[index].l + tree[index].r) >> 1;
            if (mid >= r) modify(index*2,l,r,val);
            else if (mid + 1 <= l) modify(index*2+1,l,r,val);
            else {
                modify(index*2,l,mid,val);
                modify(index*2+1,mid+1,r,val);
            }
            pushup(index);
        }
    }
    
    inline int query(int index,int l,int r,int val) {
        int mid;
        if (tree[index].opt != -1) pushdown(index);
        if ((tree[index].l == l) && (tree[index].r == r)) return tree[index].sum[val];
        else {
            mid = (tree[index].l + tree[index].r) >> 1;
            if (mid >= r) return query(index*2,l,r,val);
            else if (mid + 1 <= l) return query(index*2+1,l,r,val);
            else return query(index*2,l,mid,val) + query(index*2+1,mid+1,r,val);
        }
    }
    
    inline int Install(int x) {
        int tp = top[x],
            ans = 0;
        while (tp) {
            ans += query(1,id[tp],id[x],0); 
            modify(1,id[tp],id[x],1);
            x = fa[tp]; tp = top[x];
        }    
        ans += query(1,1,id[x],0);
        modify(1,1,id[x],1);
        return ans;
    } 
    
    inline int Uninstall(int x) {
         int ans = query(1,id[x],id[x]+size[x]-1,1);    
        modify(1,id[x],id[x]+size[x]-1,0);
        return ans;
    }
    
    int main() {
        
        read(N); 
        
        for (i = 1; i < N; i++) {
            read(x);
            E[x].push_back(i);
        }
        
        depth[0] = 1;
        dfs1(0);
        dfs2(0,0);
        
        build(1,1,num);
        
        read(Q);
        while (Q--) {
            cin >> type;
            if (type == "install") {
                read(x);
                writeln(Install(x));
            } else {
                read(x); 
                writeln(Uninstall(x));
            }
        }
        
        return 0;
    }
  • 相关阅读:
    关于同余最短路
    【水】关于 __attribute__
    题解【AtCoder
    一些简单图论问题
    浅谈简单动态规划
    关于博客园主题(美化博客园)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第47章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第46章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第45章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第44章 读书笔记(待更新)
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196437.html
Copyright © 2011-2022 走看看