bzoj4196: [Noi2015]软件包管理器

Posted sssy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4196: [Noi2015]软件包管理器相关的知识,希望对你有一定的参考价值。

题目链接

bzoj4196: [Noi2015]软件包管理器

题解

看来我还没忘Qwq
一个std随便打,12- min 1A,刺激,好吧,其实很慢

题解

#include<bits/stdc++.h> 
using namespace std; 
inline int read() { 
    int x = 0,f = 1; char c = getchar(); 
    while(c < '0' || c > '9') c = getchar(); 
    while(c <= '9' && c >= '0')x = x * 10 + c- '0',c = getchar(); 
    return x ; } 
const int maxn = 200007; 
struct node { 
     int v,next; 
}edge[maxn << 1]; 
int head[maxn],num =0 ; 
inline void add_edge(int u,int v)  { 
     edge[++ num].v = v;edge[num].next = head[u];head[u] = num; 
} 
int n,m; 
 
int son[maxn],siz[maxn],deep[maxn],fa[maxn]; 
void dfs1(int x) { 
    siz[x] = 1 ;deep[x] = deep[fa[x]] + 1; 
    for(int i = head[x];i;i = edge[i].next) { 
        int v = edge[i].v; 
        if(deep[v])continue; 
        fa[v] = x; dfs1(v); 
        siz[x] += siz[v]; 
        if(siz[v] > siz[son[x]] || !son[x]) son[x] = v; 
    } 
} 
int pos[maxn],_pos = 0,top[maxn];  
void dfs2(int x,int topfa) { 
    top[x] = topfa; pos[x] = ++_pos; 
    if(!son[x]) return;  
    dfs2(son[x],topfa);  
    for(int  i = head[x];i;i = edge[i].next) {  
        int v = edge[i].v;  
        if(v == son[x] || v == fa[x]) continue;  
        dfs2(v,v);  
    }  
}  
 
int sum[maxn << 2],tag[maxn << 2]; 
#define lc rt << 1
#define rc rt << 1 | 1
inline void update(int rt) { sum[rt] = sum[lc] + sum[rc]; } 
void pushdown(int rt,int l,int r) { 
    int mid = l + r >> 1; 
    tag[lc] = tag[rt];tag[rc] = tag[rt]; 
    sum[lc] = tag[rt] * (mid - l + 1); 
    sum[rc] = tag[rt] * (r - mid); 
    tag[rt] = -1; 
} 
int T_query(int rt,int l,int r,int tl,int tr) { 
    if(l >= tl && r <= tr) return sum[rt]; 
    if(tag[rt] >= 0) pushdown(rt,l,r); 
    int mid = l + r >> 1,ret = 0; 
    if(tl <= mid) ret += T_query(lc,l,mid,tl,tr); 
    if(tr > mid)  ret += T_query(rc,mid + 1,r,tl,tr); 
    return ret;  
} 
void T_modify(int rt,int l,int r,int tl,int tr,int ty) { 
    if(l >= tl && r <= tr) { 
        sum[rt] = ty * (r - l + 1); 
        tag[rt] = ty; return; 
    } 
    if(tag[rt] >= 0) pushdown(rt,l,r); 
    int mid = l + r >> 1; 
    if(tl <= mid) T_modify(lc,l,mid,tl,tr,ty); 
    if(tr > mid)  T_modify(rc,mid + 1,r,tl,tr,ty); 
    update(rt); 
}  
int Q1(int x) { 
    int ret = 0; 
    for(;top[x] != 1;x = fa[top[x]]) {  
        ret += T_query(1,1,n,pos[top[x]],pos[x]); 
        T_modify(1,1,n,pos[top[x]],pos[x],1); 
    } //x = fa[top[x]]; 
    ret += T_query(1,1,n,pos[1],pos[x]); 
    T_modify(1,1,n,pos[1],pos[x],1); 
    return ret; 
}   
int Q2(int x) { return T_query(1,1,n,pos[x],pos[x] + siz[x] - 1); } 
void M2(int x) { T_modify(1,1,n,pos[x],pos[x] + siz[x] - 1,0);  } 
int main() { 
    n = read(); 
    for(int k,i = 2;i <= n;++ i) { 
        k = read() + 1;  
        add_edge(k,i),add_edge(i,k) ; 
    }    
    dfs1(1); 
    dfs2(1,1); 
    memset(tag,-1,sizeof tag); 
    //build(1,1,n); 
    char ch[10]; 
    int q = read(),k; 
    while(q --) {  
        scanf("%s",ch + 1); 
        if(ch[1] == 'i') { 
            k = read() + 1; 
            printf("%d
",deep[k] - Q1(k)); 
        } 
        else { 
            k = read() + 1; 
            printf("%d
",Q2(k)); 
            M2(k);      
         } 
    } 
    return 0; 
}

以上是关于bzoj4196: [Noi2015]软件包管理器的主要内容,如果未能解决你的问题,请参考以下文章

Bzoj 4196: [Noi2015]软件包管理器 树链剖分

bzoj4196: [Noi2015]软件包管理器

[UOJ#128][BZOJ4196][Noi2015]软件包管理器

bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

bzoj4196[Noi2015]软件包管理器

BZOJ_4196_[Noi2015]软件包管理器_树链剖分