[NOI2015]软件包管理器 树链剖分_线段树

[NOI2015]软件包管理器 树链剖分_线段树

没有太大难度,刷水有益健康

Code:

// luogu-judger-enable-o2
#include <bits/stdc++.h>
#define setIO(s) freopen(s".in","r",stdin) 
#define maxn 100002 
using namespace std;
int read()
{
    int f=1,x=0;
    char ss=getchar();
    while(ss<'0'||ss>'9'){if(ss=='-')f=-1;ss=getchar();}
    while(ss>='0'&&ss<='9'){x=x*10+ss-'0';ss=getchar();}
    return f*x;
}

void print(int x)
{
    if(x<0){putchar('-');x=-x;}
    if(x>9)print(x/10);
    putchar(x%10+'0');
}
namespace Seg
{
    #define lson (x << 1)
    #define rson ((x << 1) | 1) 
    int sumv[maxn << 2], lazy[maxn << 2]; 
    void mark_tag(int l, int r, int x, int delta)
    {     
        sumv[x] = (r - l + 1) * delta, lazy[x] = delta; 
    }
    void pushdown(int l, int r, int x)
    {   
        if(lazy[x] == -1) return ; 
        int mid = (l + r) >> 1; 
        if(mid >= l) mark_tag(l, mid, lson, lazy[x]); 
        if(mid < r) mark_tag(mid + 1, r, rson, lazy[x]); 
        lazy[x] = -1; 
    }
    int query(int l, int r, int x, int L, int R)
    {
        if(l >= L && r <= R)
        {
            return sumv[x]; 
        }
        pushdown(l, r, x); 
        int mid = (l + r) >> 1; 
        int t = 0; 
        if(L <= mid)  t += query(l, mid, lson, L, R); 
        if(R > mid) t += query(mid + 1, r, rson, L, R); 
        return t; 
    }
    void update(int l, int r, int x, int L, int R, int d)
    {
        if(l >= L && r <= R)
        {
            mark_tag(l, r, x, d); 
            return ; 
        }
        pushdown(l, r, x); 
        int mid = (l + r) >> 1; 
        if(L <= mid) update(l, mid, lson, L, R, d); 
        if(R > mid) update(mid + 1, r, rson, L, R, d); 
        sumv[x] = sumv[lson] + sumv[rson]; 
    }
}; 
int hd[maxn], to[maxn], nex[maxn], fa[maxn], siz[maxn], top[maxn], hson[maxn], dep[maxn]; 
int st[maxn], ed[maxn], dfn[maxn]; 
int edges, n, Q, root = 1, tim; 
char str[100]; 
void add(int u, int v)
{
    nex[++edges] = hd[u], hd[u] = edges, to[edges] = v; 
}   
void dfs1(int u)
{
    siz[u] = 1, dep[u] = dep[fa[u]] + 1;  
    for(int i = hd[u]; i ; i = nex[i])
    {
        dfs1(to[i]), siz[u] += siz[to[i]]; 
        if(siz[to[i]] > siz[hson[u]]) hson[u] = to[i]; 
    }
}
void dfs2(int u, int tp)
{
    dfn[u] = ++tim, top[u] = tp;
    st[u] = tim; 
    if(hson[u]) 
        dfs2(hson[u], tp);  
    for(int i = hd[u]; i ; i = nex[i])
    {
        if(to[i] != hson[u]) dfs2(to[i], to[i]); 
    }
    ed[u] = tim; 
}
int lookup(int x)
{
    int t = 0; 
    while(x)
    {
        t += Seg :: query(1, n, 1, dfn[top[x]], dfn[x]); 
        Seg :: update(1, n, 1, dfn[top[x]], dfn[x], 1); 
        x = fa[top[x]]; 
    }
    return t; 
} 
int main()
{
   //  setIO("input"); 
    n=read();  
    for(int i = 2; i <= n; ++i)
    {
        fa[i]=read(), ++fa[i], add(fa[i], i);            
    }
    dfs1(1), dfs2(1, 1);      
    memset(Seg::lazy, -1, sizeof(Seg :: lazy)); 
    Q=read(); 
    while(Q--)
    {     
        int u; 
        scanf("%s",str);
        u=read(); 
        u+=1; 
        if(str[0] == 'i') 
        {
            print(dep[u] - lookup(u)); 
            printf("\n"); 
        } 
        if(str[0] == 'u') 
        {
            print(Seg :: query(1, n, 1, st[u], ed[u])); 
            Seg :: update(1, n, 1, st[u], ed[u], 0);
            printf("\n");  
        }
    }
    return 0; 
}

  

posted @ 2019-06-09 17:28 EM-LGH 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值