• 【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;
    }
  • 相关阅读:
    hdu 1286
    hdu 1420
    hdu 2068
    hdu 1718
    hdu 1231
    hdu 1072
    HDOJ 350留念
    hdu 1898
    hdu 1593
    帮助理解git的图
  • 原文地址:https://www.cnblogs.com/evenbao/p/9196437.html
Copyright © 2020-2023  润新知