1、题目大意:讲道理,就是让你有两个修改一个是把一个点到根的路径上的点权值全部变成1,另一个是把一个子树全部变成0

然后让你输出每次修改,改变的哪些节点的值

2、分析:就是一个树剖,树剖是满足dfs序的,然后我们就相当于建了一个既符合树剖,又满足dfs序的线段树,然后就在线段树上询
问就可以了

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1000000
struct tree_chain_parition{
    int Size[M], Top[M], Fa[M], Height[M], num[M];
    int tot, ST_tot;
    int left[M], right[M];
    int son[M], head[M], Next[M];
    int n;
    int q[M], lazy[M];
    inline void init(){
        memset(head, -1, sizeof(head));
        memset(lazy, -1, sizeof(lazy));
        tot = ST_tot = 0;
        Top[1] = 1;
    }
    inline void pushdown(int l, int r, int o){
        int mid = (l + r) / 2;
        if(lazy[o] != -1){
            q[2 * o] = (mid - l + 1) * lazy[o];
            q[2 * o + 1] = (r - mid) * lazy[o];
            lazy[2 * o] = lazy[2 * o + 1] = lazy[o];
            lazy[o] = -1;
        }
    }
    inline void add(int l, int r, int o, int x, int y, int k){
        if(x <= l && r <= y){
            q[o] = (r - l + 1) * k;
            lazy[o] = k;
            return;
        }
        pushdown(l, r, o);
        int mid = (l + r) / 2;
        if(x <= mid) add(l, mid, 2 * o, x, y, k);
        if(y > mid) add(mid + 1, r, 2 * o + 1, x, y, k);
        q[o] = q[2 * o] + q[2 * o + 1];
    }
    inline int query(int l, int r, int o, int x, int y){
        if(x <= l && r <= y){
            return q[o];
        }
        pushdown(l, r, o);
        int mid = (l + r) / 2;
        int ret = 0;
        if(x <= mid) ret += query(l, mid, 2 * o, x, y);
        if(y > mid) ret += query(mid + 1, r, 2 * o + 1, x, y);
        return ret;
    }
    inline int insert(int x, int y){
        tot ++;
        son[tot] = y;
        Next[tot] = head[x];
        head[x] = tot;
    }
    inline void dfs1(int x, int fa, int height){
        Height[x] = height;
        Fa[x] = fa;
        for(int i = head[x]; i != -1; i = Next[i]){
            dfs1(son[i], x, height + 1);
            Size[x] += Size[son[i]];
        }
        Size[x] ++;
    }
    inline void dfs2(int x, int fa){
        ST_tot ++;
        num[x] = ST_tot;
        left[x] = ST_tot;
        int o = 0, ss = 0;
        for(int i = head[x]; i != -1; i = Next[i]){
            if(Size[son[i]] > ss){
                o = i;
                ss = Size[son[i]];
            }
        }
        if(o != 0){
            Top[son[o]] = Top[x];
            dfs2(son[o], x);
        }
        for(int i = head[x]; i != -1; i = Next[i]) if(o != i){
            Top[son[i]] = son[i];
            dfs2(son[i], x);
        }
        right[x] = ST_tot;
    }
    inline int Install(int x){
        int y = 1;
        int ret = 0;
        while(Top[x] != Top[y]){
            if(Height[Top[x]] < Height[Top[y]]) swap(x, y);
            ret += (num[x] - num[Top[x]] + 1) - query(1, n, 1, num[Top[x]], num[x]);
            add(1, n, 1, num[Top[x]], num[x], 1);
            x = Fa[Top[x]];
        }
        if(Height[x] < Height[y]) swap(x, y);
        ret += (num[x] - num[y] + 1) - query(1, n, 1, num[y], num[x]);
        add(1, n, 1, num[y], num[x], 1);
        return ret;
    }
    inline int Unstall(int x){
        int ret = query(1, n, 1, left[x], right[x]);
        add(1, n, 1, left[x], right[x], 0);
        return ret;
    }
} wt;
int main(){
    int n;
    scanf("%d", &n);
    wt.n = n;
    wt.init();
    for(int i = 2; i <= n; i ++){
        scanf("%d", &wt.Fa[i]);
        wt.Fa[i] ++;
        wt.insert(wt.Fa[i], i);
    }
    wt.dfs1(1, -1, 1);
    wt.dfs2(1, -1);
    int m;
    scanf("%d", &m);
    char str[20];
    int x;
    for(int i = 1; i <= m; i ++){
        scanf("%s%d", str, &x);
        x ++;
        if(str[0] == 'i'){
            printf("%d\n", wt.Install(x));
        }
        else printf("%d\n", wt.Unstall(x));
    }
    return 0;
}

BZOJ4196——noi2015软件包管理器的更多相关文章

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

    [UOJ#128][BZOJ4196][Noi2015]软件包管理器 试题描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管 ...

  2. [BZOJ4196][NOI2015]软件包管理器(树链剖分)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2166  Solved: 1253[Submit][Sta ...

  3. [BZOJ4196][NOI2015]软件包管理器

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1040  Solved: 603[Submit][Stat ...

  4. [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树

    软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...

  5. BZOJ4196[Noi2015]软件包管理器——树链剖分+线段树

    题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...

  6. BZOJ4196 [Noi2015]软件包管理器 【树剖】

    题目 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件 ...

  7. BZOJ4196: [Noi2015]软件包管理器(树链剖分)

    Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...

  8. bzoj4196 [Noi2015]软件包管理器 树链剖分+线段树

    先把树剖分了(又是dfs1.dfs2),然后区间求和.区间覆盖即可 难得的1A好(shui)题 ——写了那么多题,终于有一道是1A的了,加上上一次连续交了几遍A的程序,我的状态莫名好看啊233 总结: ...

  9. bzoj4196 [Noi2015]软件包管理器——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4196 树链剖分. 代码如下: #include<iostream> #inclu ...

随机推荐

  1. SQL Server编程(04)基本语法【转载】

    一.定义变量 --简单赋值 declare @a int set @a=5 print @a   --使用select语句赋值 declare @user1 nvarchar(50) select @ ...

  2. HTTPS 客户端验证 服务端证书流程

    网上的文章很多, 但是对摘要的验证流程不够通俗易懂. QQ截图20160420114804.png 证书预置和申请 1:客户端浏览器会预置根证书, 里面包含CA公钥2:服务器去CA申请一个证书3: C ...

  3. WSADATA

    中文名 WSADATA 操作系统 Windows CE 版本: 大于等于1.0 定义位置: Winsock.h 目录 1 说明 2 结构原型 3 参数说明 4 备注 说明编辑 WSADATA结构被用来 ...

  4. fcc的高级算法题

    核心提示:本部分一个9道题,给定时间50小时.属于fcc前端学习的"高级编程脚本"题,对于初学者来说,确实算是"高级"了.如果只想着闭门造车,50小时确实也不过 ...

  5. Google 谷歌网页搜索, 学术搜索

    Google 谷歌网页搜索, 学术搜索 1. 网页搜索引擎-Google * https://letsgg.tk/ * https://google.kfd.me/ 谷歌搜索镜像:  http://d ...

  6. Jetty多Connector

    有时候想要启动两个端口,或者通过一个Jetty server提供多个不同服务,比如说使用8080来指定默认访问端口,使用8433指定https访问端口等等,此时就可以通过创建多个Connector来解 ...

  7. [转]asp.net webform 与mvc 共享session

    公司内部系统最早是用.net webform模式开发的,现新项目用.net mvc 开发,现存在的问题就是如何保持原有.net webform的登录状态不变,而在mvc中能够验证用户的登录状态,也就是 ...

  8. Genymotion启动时出现错误virtualization engine not found

    打开VirtualBox,管理-全局设定,网络,仅主机“Host-only”网络,需要的设置如下

  9. linux socket

    linux 的 C 库路径为  /usr/include,可以直接查看源码,也可以通过 "man 头文件名" 来学习,需要查看某个函数如 bind() ,则只需要 man 2 bi ...

  10. CSS3:flex布局应用

    想把先前的整理的东西贴出来,怎奈总是有额外事情发生,额,教训电脑要离水杯远点~~ 推荐一本书,<编写可维护的Javascript>这是Nicbolas C.Zakas写的,他的<Ja ...