NOI2015 软件包管器

https://www.luogu.org/problem/P2146

题意

维护一棵树,每个节点都有一个为0或1的值,初始值全为0

需要支持

将一条链上的点都变成1,

将一棵子树中的点都变成0,

并统计每次操作改变了多少点的状态。

分析

每次修改链的时候,要记住,他们可能不在同一条重链上(其它题目里面的链修改也要注意),所以,我们需要跳...ctrl

线段树维护区间和,tag表示全改为0/1即可

(遇到错误不要慌!!!手模拟一遍样例说不定就找到错误了

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 100000+99;
const int MAXM = MAXN<<1; int n,m;
struct node{
int deep, size, son, fa, tp, in, out;
}a[MAXN];
int _clock; int head[MAXN], cnt;
struct seg{
int y, next;
}e[MAXM];
void add_edge(int x, int y) {
e[++cnt].y = y;
e[cnt].next = head[x];
head[x] = cnt;
} void dfs1(int x, int fa) {
a[x].fa = fa;
a[x].deep = a[fa].deep + 1;
a[x].size = 1;
for(int i = head[x]; i; i = e[i].next)
if(e[i].y != fa) {
dfs1(e[i].y, x);
a[x].size += a[e[i].y].size;
a[x].son = a[a[x].son].size > a[e[i].y].size ? a[x].son : e[i].y ;
}
} void dfs2(int x, int tp) {
a[x].tp = tp;
a[x].in = ++_clock;
if(a[x].son) dfs2(a[x].son , tp);
for(int i = head[x]; i; i = e[i].next)
if(e[i].y != a[x].fa && e[i].y != a[x].son) {
dfs2(e[i].y , e[i].y);
}
a[x].out = _clock;
} struct tree{
int sum, lazyset;
tree (int sum = 0, int lazyset = -1) : sum(sum), lazyset(lazyset) {}
}tr[MAXN<<2]; void pushup(int o) {tr[o].sum = tr[o<<1].sum + tr[o<<1|1].sum;} void pushdown(int o, int l, int r) {
if(tr[o].lazyset == -1) return ;
tr[o<<1].lazyset = tr[o<<1|1].lazyset = tr[o].lazyset ;
int mid = (l+r)>>1;
tr[o<<1].sum = tr[o].lazyset * (mid-l+1);
tr[o<<1|1].sum = tr[o].lazyset * (r-mid);
tr[o].lazyset = -1;
}
void optset(int o, int l, int r, int ql, int qr, int k) {
if(ql <= l && r <= qr) {
tr[o].sum = k*(r-l+1);
tr[o].lazyset = k;
return ;
}
pushdown(o, l, r);
int mid = (l+r)>>1;
if(ql <= mid) optset(o<<1, l, mid, ql, qr, k);
if(mid < qr) optset(o<<1|1, mid+1, r, ql, qr, k);
pushup(o);
}
int query(int o, int l, int r, int ql, int qr) {
if(ql <= l && r <= qr) return tr[o].sum;
pushdown(o, l, r);
int mid = (l+r)>>1, ans = 0;
if(ql <= mid) ans += query(o<<1, l, mid, ql, qr);
if(mid < qr) ans += query(o<<1|1, mid+1, r, ql, qr);
return ans;
} int update_lian(int x) {
int ans = 0;
while(a[x].tp != 1) {
ans += (a[x].in-a[a[x].tp].in+1) - query(1, 1, n, a[a[x].tp].in, a[x].in);
optset(1, 1,n, a[a[x].tp].in, a[x].in, 1);//这题我没想边界咋找,于是就每一步都减一下
x = a[a[x].tp].fa;
}
ans += (a[x].in-a[a[x].tp].in+1) - query(1, 1, n, a[a[x].tp].in, a[x].in);
optset(1, 1, n, a[a[x].tp].in, a[x].in, 1);
return ans;
} int update_tree(int x) {
int ans = query(1, 1, n, a[x].in, a[x].out);
optset(1, 1, n, a[x].in, a[x].out , 0);
return ans;
} int main() {
scanf("%d",&n);
int x,y;
for(x = 2; x <= n; x++) {
scanf("%d",&y);
y++;
add_edge(x, y);
add_edge(y, x);
}
dfs1(1, 0);
dfs2(1, 1);
scanf("%d",&m);
string cmd;
for(int i = 1; i <= m; i++) {
cin>>cmd;
scanf("%d",&x);
x++;
if(cmd[0] == 'i') {
printf("%d\n",update_lian(x));
} else {
printf("%d\n",update_tree(x));
}
}
}

NOI2015 软件包管器的更多相关文章

  1. BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]

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

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

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

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

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 721  Solved: 419[Submit][Statu ...

  4. [NOI2015]软件包管理器

    4621 [NOI2015]软件包管理器  题目等级 : 钻石 Diamond   题目描述 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过 ...

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

    BZOJ_4196_[Noi2015]软件包管理器_树链剖分 题意: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助 ...

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

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

  7. 洛谷 P2146 [NOI2015]软件包管理器 解题报告

    P2146 [NOI2015]软件包管理器 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...

  8. 【BZOJ4196】[Noi2015]软件包管理器 树链剖分

    [Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...

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

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

随机推荐

  1. 监控redis命令 - monitor

    有时候我们需要知道客户端对redis服务端做了哪些命令操作.我们可以试用monitor命令来查看.它能清楚的看到客户端在什么时间点执行了那些命令. MONITOR 是一个调试命令,每个命令流回来的re ...

  2. 记录Ubuntu下使用docker使用

    关键词:docker.Dockerfile等等. 这里主要记录Ubuntu下docker使用细节. 首先是如何安装,然后如何创建docker镜像.搭建docker服务器.运行使用docker. 1. ...

  3. Docker启动守护式容器

    目录 启动守护式容器 查看容器日志 docker后台运行 查看容器内运行的进程 ​查看容器内部细节 进入正在运行的容器并以命令行交互 重新进入 上述两个区别 从容器内拷贝文件到主机上 启动守护式容器 ...

  4. AcWing 77. 翻转单词顺序

    习题地址 https://www.acwing.com/problem/content/description/73/ 题目描述输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变. 为简单 ...

  5. 注意设置httpclient连接数

    在使用Httpclient的过程中,当访问量增大的时候,会发现本地的连接等待时间急剧增加,例如从400ms增加到 78000ms,之前一直以为是航信系统问题,后面经过检查才发现,原来是本地httpcl ...

  6. CF732D Exams

    这题可以用二分答案来做 那么为什么可以用二分答案呢? 答案当然是满足了单调性. 假设用\(x\)天能够考完所有试,那么用大于$x $天必定也能够考完所有试,所以满足了单调性,我们就可以二分答案 那么如 ...

  7. hive on spark 常用配置

    常用设置 reset; set hive.execution.engine=spark; set hive.map.aggr = false; set hive.auto.convert.join = ...

  8. Docker - 卷组管理(三)

    一.不指定宿主机目录 首先运行一个nginx容器 docker run -d --name mynginx -p 8080:80 -v /usr/share/nginx/html nginx --na ...

  9. 【git】代码回退指定commit

    [注意:如果提交的错误代码较少,可以在本地修改成 commit之前的正确代码样子,然后再提交一次即可.不用麻烦的操作回滚.] 开发人员错误将代码提交到gitlab的远程dev分支,回滚方法如下: 1. ...

  10. 关于WIN7下IE8IE7浏览器无法安装微信支付商户证书的解决方案

    关于WIN7下IE8IE7浏览器无法安装微信支付商户证书的解决方案 解决方案就是使用 chrome浏览器 默认的chorme浏览器  打开微信商户平台 会提示让安装控件  然后反复安装 其实要解决这个 ...