NOI 2015 软件包管理器

来源:互联网 发布:一加二线刷包驱动端口 编辑:程序博客网 时间:2024/06/05 17:28

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

题解:

/*题目                  提交者 结果   用时    内存  语言NOI 2015 软件包管理器 saruka  100  2442ms 17712kb C++*//*<NOI 2015 题解 :http://www.cnblogs.com/Robert-Yuan/p/5584737.html>*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100010;inline int getint(){    int r = 0, k = 1;    char c = getchar();    for(; c < '0' || c > '9'; c = getchar())        if(c == '-') k = -1;    for(; c >= '0' && c <= '9'; c = getchar())        r = r * 10 + c - '0';    return r * k;}struct Node{    int data, next;} node[maxn];#define now node[point].data#define then node[point].nextstruct Tree{    int sm, pt;    Tree() { pt = -1; }} s[maxn * 17];int n, cnt, Idex;int head[maxn], Sz[maxn], Son[maxn], fa[maxn];int id[maxn], el[maxn], hd[maxn];void addedge(int u, int v){    node[cnt].data = v;    node[cnt].next = head[u];    head[u] = cnt++;}void dfs1(int x){    Sz[x] = 1;    Son[x] = -1;    for(int point = head[x]; point != -1; point = then)    {        dfs1(now);        Sz[x] += Sz[now];        if(Son[x] < 0 || Sz[now] > Sz[Son[x]]) Son[x] = now;    }} void dfs2(int x, int tp){    id[x] = ++Idex;    hd[x] = tp;    if(Son[x] < 0)    {        el[x] = Idex;        return;    }    dfs2(Son[x], tp);    for(int point = head[x]; point != -1; point = then)    {        if(now!=Son[x])        {            dfs2(now, now);        }    }    el[x] = Idex;}void Push_down(int o, int l, int r){    if(s[o].pt != -1)    {        int mid = (l + r) >> 1;        s[o << 1].pt = s[o].pt;        s[o << 1].sm = (mid - l + 1) * s[o].pt;        s[o << 1 | 1].pt = s[o].pt;        s[o << 1 | 1].sm = (r - mid) * s[o].pt;        s[o].pt = -1;    }} void Update(int o){    s[o].sm = s[o << 1].sm + s[o << 1 | 1].sm;}void Modify(int o, int l, int r, int al, int ar, int d){    Push_down(o, l, r);    if(l == al && r == ar)    {        s[o].pt = d;        s[o].sm = (r - l + 1) * d;        return;    }    int mid = (l + r) >> 1;    if(al > mid) Modify(o << 1 | 1, mid + 1, r, al, ar, d);    else if(ar <= mid) Modify(o << 1, l, mid, al, ar, d);    else    {        Modify(o << 1 | 1, mid + 1, r, mid + 1, ar, d);        Modify(o << 1, l, mid, al, mid, d);    }    Update(o);}int Ask(int o, int l, int r, int x){    Push_down(o, l, r);    if(l == r) return s[o].sm;    int mid = (l + r) >> 1;    if(x > mid) return Ask(o << 1 | 1, mid + 1, r, x);    return Ask(o << 1, l, mid, x);}void Add(int x){    int last;    while(x)    {        Modify(1, 1, n, id[hd[x]], id[x], 1);        x = fa[hd[x]];    }}void Del(int x){    Modify(1, 1, n, id[x], el[x], 0);}int main(){    int x, T, sum1, sum2;    char ord[10];    n = getint();    for(int i = 1; i <= n; i++) head[i] = -1;    for(int i = 2; i <= n; i++)    {        x = getint();        addedge(x + 1, i);        fa[i] = x + 1;    }    dfs1(1);    dfs2(1, 1);    T = getint();    while(T--)    {        scanf("%s%d", ord, &x);        x++;        if(ord[0] == 'i')        {            if(Ask(1, 1, n, id[x]) == 1)            {                puts("0\n");            }            else            {                sum1 = s[1].sm;                Add(x);                printf("%d\n", s[1].sm - sum1);            }        }        else        {            if(Ask(1, 1, n, id[x]) == 0)            {                puts("0\n");            }            else            {                sum1 = s[1].sm;                Del(x);                printf("%d\n", sum1 - s[1].sm);            }        }    }    return 0;}

Powered By Saruka
Copyright © 2016 All Rights Reserved.

0 0