BZOJ4196——noi2015软件包管理器
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软件包管理器的更多相关文章
- [UOJ#128][BZOJ4196][Noi2015]软件包管理器
[UOJ#128][BZOJ4196][Noi2015]软件包管理器 试题描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管 ...
- [BZOJ4196][NOI2015]软件包管理器(树链剖分)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2166 Solved: 1253[Submit][Sta ...
- [BZOJ4196][NOI2015]软件包管理器
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1040 Solved: 603[Submit][Stat ...
- [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树
软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...
- BZOJ4196[Noi2015]软件包管理器——树链剖分+线段树
题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...
- BZOJ4196 [Noi2015]软件包管理器 【树剖】
题目 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件 ...
- BZOJ4196: [Noi2015]软件包管理器(树链剖分)
Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...
- bzoj4196 [Noi2015]软件包管理器 树链剖分+线段树
先把树剖分了(又是dfs1.dfs2),然后区间求和.区间覆盖即可 难得的1A好(shui)题 ——写了那么多题,终于有一道是1A的了,加上上一次连续交了几遍A的程序,我的状态莫名好看啊233 总结: ...
- bzoj4196 [Noi2015]软件包管理器——树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4196 树链剖分. 代码如下: #include<iostream> #inclu ...
随机推荐
- XML学习笔记
XML学习笔记 第一部分:XML简介 我们经常可以听到XML.HTML.XHTML这些语言,后两者比较清楚,一直不是很明白XML是什么,这里做一个总结. XML(eXtensible Markup L ...
- Python与C++结构体交互
需求:根据接口规范,实现与服务端的数据交互 服务端结构体分包头.包体.包尾 包头C++结构体示例如下 typedef struct head { BYTE string1; BYTE string2; ...
- 忘记常访问网站密码怎么办?教你如何查看浏览器已保存的密码,如何简单查看Chome浏览器保存的密码?
利用场景: 同事或朋友外出有事,电脑未锁屏离开座位.可以利用这一间隙,查看Ta在Chrome浏览器上保存的账号密码 查看逻辑: 当我们要查看Chrome浏览器上保存的密码时,点击显示,会弹出一个对话框 ...
- 获取jsp页面的宽和高
var winWidth; var winHeight; function getResult() { if(window.innerWidth) { winWidth=window.innerWid ...
- WinForm------窗体初始化位置的显示
在窗体的构造方法里面添加 public Form2() { InitializeComponent(); //指定窗口初始化时的位置(计算机屏幕中间) this.StartPosition = For ...
- 20145212 《Java程序设计》第5周学习总结
20145212 <Java程序设计>第5周学习总结 教材学习内容总结 第八章 1.Java中所有错误都会被打包为对象,通过try和catch语法可以对代表错误的对象做处理. try{ . ...
- 固定导航(Sticky nav)
方法1: <div class="footer"></div> .footer{ position:fixed; bottom:0; left:0; wid ...
- Java面试笔记
1.&和&& if(str != null& !str.equals("")){ System.out.println("ok" ...
- Loader Generator---loading图片生成器
if(公司配有专业的设计师) return; Recommend("http://loadergenerator.com/");
- Spring 事务传递教程_有实例
通过这篇文章,你将学习到Spring框架中中事务的传递 简介 在处理Spring管理的事务时,开发人员可以以传播的方式定义事务的行为.换句话说,开发人员能够决定业务方法如何被封装在逻辑和物理事务中.来 ...