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

    传送门

    最近学了树剖我们来做几道题练练手。

    这个题我觉得也是板子题啊……

    反正就是对于一个安装操作,就在它自己所在链向上跳,如果当前链顶已经被安装的话计算一下从这个点到链顶还有多少没被安装即可。每次向上跳的时候都要把经过的链上的点全改为1.至于卸载操作就更简单了,直接先统计自己子树内有多少节点值为1的儿子(已安装软件),之后区间修改为0即可。如果这个点已经被安装/卸载相对应的就可以不执行这次操作。

    这题还是很好写的,一次AC。(之后就是树剖无限bug的开始)

    看一下代码。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<queue>
    #include<set>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    
    using namespace std;
    typedef long long ll;
    const int M = 100005;
    
    int read()
    {
        int ans = 0,op = 1;
        char ch = getchar();
        while(ch < '0' || ch > '9')
        {
        if(ch == '-') op = -1;
        ch = getchar();
        }
        while(ch >= '0' && ch <= '9')
        {
        ans *= 10;
        ans += ch - '0';
        ch = getchar();
        }
        return ans * op;
    }
    
    struct seg
    {
        int v,lazy;
    }t[M<<2];
    
    struct edge
    {
        int next,to,from;
    }e[M<<1];
    
    int n,dfn[M],rk[M],a[M],size[M],dep[M],fa[M],hson[M],q,x,y,head[M],ecnt,idx,top[M];
    char s[15];
    
    void add(int x,int y)
    {
        e[++ecnt].to = y;
        e[ecnt].from = x;
        e[ecnt].next = head[x];
        head[x] = ecnt;
    }
    
    void dfs1(int x,int f,int depth)
    {
        size[x] = 1,dep[x] = depth,fa[x] = f;
        int maxson = -1;
        for(int i = head[x];i;i = e[i].next)
        {
        if(e[i].to == f) continue;
        dfs1(e[i].to,x,depth+1);
        size[x] += size[e[i].to];
        if(size[e[i].to] > maxson) maxson = size[e[i].to],hson[x] = e[i].to;
        }
    }
    
    void dfs2(int x,int t)
    {
        dfn[x] = ++idx,top[x] = t;
        if(!hson[x]) return;
        dfs2(hson[x],t);
        for(int i = head[x];i;i = e[i].next)
        {
        if(e[i].to == fa[x] || e[i].to == hson[x]) continue;
        dfs2(e[i].to,e[i].to);
        }
    }
    
    void build(int p,int l,int r)
    {
        if(l == r)
        {
        t[p].lazy = -1;
        return;
        }
        int mid = (l+r) >> 1;
        build(p<<1,l,mid),build(p<<1|1,mid+1,r);
    }
    
    void pushdown(int p,int l,int r)
    {
        int mid = (l+r) >> 1;
        t[p<<1].lazy = t[p].lazy,t[p<<1|1].lazy = t[p].lazy;
        t[p<<1].v = t[p].lazy * (mid-l+1),t[p<<1|1].v = t[p].lazy * (r-mid);
        t[p].lazy = -1;
    }
    
    int query(int p,int l,int r,int kl,int kr)
    {
        if(l == kl && r == kr) return t[p].v;
        int mid = (l+r) >> 1;
        if(t[p].lazy != -1) pushdown(p,l,r);
        if(kr <= mid) return query(p<<1,l,mid,kl,kr);
        else if(kl > mid) return query(p<<1|1,mid+1,r,kl,kr);
        else return query(p<<1,l,mid,kl,mid) + query(p<<1|1,mid+1,r,mid+1,kr);
    }
    
    void modify(int p,int l,int r,int kl,int kr,int val)
    {
        if(l == kl && r == kr)
        {
        t[p].lazy = val,t[p].v = val * (r-l+1);
        return;
        }
        int mid = (l+r) >> 1;
        if(t[p].lazy != -1) pushdown(p,l,r);
        if(kr <= mid) modify(p<<1,l,mid,kl,kr,val);
        else if(kl > mid) modify(p<<1|1,mid+1,r,kl,kr,val);
        else modify(p<<1,l,mid,kl,mid,val),modify(p<<1|1,mid+1,r,mid+1,kr,val);
        t[p].v = t[p<<1].v + t[p<<1|1].v;
    }
    
    int qrange(int x)
    {
        int ans = 0;
        while(!query(1,0,n,dfn[top[x]],dfn[top[x]]))
        {
        ans += (dfn[x] - dfn[top[x]] + 1);
        modify(1,0,n,dfn[top[x]],dfn[x],1);
        x = fa[top[x]];
        }
        int g = dfn[x] - dfn[top[x]] + 1;
        // printf("#%d %d
    ",g,x);
        //printf("!%d
    ",query(1,0,n,dfn[top[x]],dfn[x]));
        ans += (g - query(1,0,n,dfn[top[x]],dfn[x])),modify(1,0,n,dfn[top[x]],dfn[x],1);
        //printf("!%d
    ",query(1,0,n,dfn[top[x]],5));
        return ans;
    }
    
    int qson(int x)
    {
        int ans = 0;
        ans += query(1,0,n,dfn[x],dfn[x] + size[x] - 1);
        modify(1,0,n,dfn[x],dfn[x] + size[x] - 1,0);
        return ans;
    }
    
    int main()
    {
        n = read();
        rep(i,1,n-1) x = read(),add(x,i),add(i,x);
        //rep(i,1,ecnt) printf("#%d %d
    ",e[i].from,e[i].to);
        dfs1(0,0,1),dfs2(0,0),build(1,0,n);
        q = read();
        while(q--)
        {
        scanf("%s",s);
        if(s[0] == 'i')
        {
            //printf("@%d
    ",query(1,0,n,0,n));
            x = read();
            if(query(1,0,n,dfn[x],dfn[x]))
            {
            printf("0
    ");
            continue;
            }
            printf("%d
    ",qrange(x));
        }
        else if(s[0] == 'u')
        {
            x = read();
            if(!query(1,0,n,dfn[x],dfn[x]))
            {
            printf("0
    ");
            continue;
            }
            printf("%d
    ",qson(x));
        }
        }
        return 0;
    }
  • 相关阅读:
    poj 2488 DFS
    畅通工程 并查集模版
    KMP 模板
    poj 1426 DFS
    poj 2528 线段数
    poj 3468 线段数 修改区间(点)
    CVPR2012文章阅读(2)A Unified Approach to Salient Object Detection via Low Rank Matrix Recovery
    如何制定目标
    Saliency Map 最新综述
    计算机视觉模式识别重要会议杂志
  • 原文地址:https://www.cnblogs.com/captain1/p/9710924.html
Copyright © 2011-2022 走看看