#\(\mathcal{\color{red}{Description}}\)

\(Link\)

一道\(zz\)的树剖题\(qwq\)。

#\(\mathcal{\color{red}{Solution}}\)

我天\(NOI\)怎么可能有这种水题啊……

很显然的就是 线段树区间染色 + 统计根到每个节点的距离 + 子树和 + 修改子树 ……

纯纯的板子啊!

\(emmmmm\)于是这道题就完了~

#include <cstdio>
#include <vector>
#include <iostream>
#define il inline
#define MAXN 200010
#define ls(x) (x << 1)
#define rs(x) (x << 1 | 1)
#define mid ((l + r) >> 1) using namespace std ;
char in[30] ;
vector <int> sons[MAXN] ; int Id[MAXN], tot ;
int dis[MAXN << 1], s[MAXN << 1], tag[MAXN << 1], i ;
int N, M, In, fa[MAXN], dep[MAXN], Top[MAXN], sub[MAXN], hs[MAXN] ; inline int qrr(){
int k = 0 ; char c = getchar() ;
while (c < '0' || c > '9') c = getchar() ;
while (c <= '9' && c >= '0') k = (k << 1) + (k << 3) + c - 48, c = getchar() ;
return k ;
}
void _dfs1(int deep, int now, int f){
dep[now] = deep, fa[now] = f ; sub[now] = 1 ;
int _hs = -1 ;
for (int k = 0 ; k < sons[now].size() ; ++ k){
_dfs1(deep + 1, sons[now][k], now) ;
sub[now] += sub[sons[now][k]] ;
if(sub[sons[now][k]] > _hs)
_hs = sub[sons[now][k]], hs[now] = sons[now][k] ;
}
}
void _dfs2(int now, int Tp){
Top[now] = Tp, Id[now] = ++ tot ;
if (!hs[now]) return ;
_dfs2(hs[now], Tp) ;
for (int k = 0 ; k < sons[now].size() ; ++ k){
if (sons[now][k] == hs[now]) continue ;
_dfs2(sons[now][k], sons[now][k]) ;
}
}
void build(int rt, int l, int r){
if (l == r) {dis[rt] = 1 ; return ;}
build(ls(rt), l, mid) ;
build(rs(rt), mid + 1, r) ;
dis[rt] = dis[ls(rt)] + dis[rs(rt)] ;
}
il void p_d(int rt, int l, int r){
if(tag[rt] != -1){
s[ls(rt)] = (mid - l + 1) * tag[rt] ;
s[rs(rt)] = (r - mid) * tag[rt] ;
tag[ls(rt)] = tag[rs(rt)] = tag[rt] ;
tag[rt] = -1 ;
}
}
int query_D(int rt, int l, int r, int ql, int qr){
int res = 0 ;
if (ql <= l && r <= qr){res += dis[rt] ; return res ;}
if (ql <= mid) res += query_D(ls(rt), l, mid, ql, qr) ;
if (qr > mid) res += query_D(rs(rt), mid + 1, r, ql, qr) ;
return res ;
}
int query_C(int rt, int l, int r, int ql, int qr){
int res = 0 ;
if (ql <= l && r <= qr){res += s[rt] ; return res ;}
p_d(rt, l, r) ;
if (ql <= mid) res += query_C(ls(rt), l, mid, ql, qr) ;
if (qr > mid) res += query_C(rs(rt), mid + 1, r, ql, qr) ;
return res ;
}
void update_C(int rt, int l, int r, int ul, int ur, int k){
if (ul <= l && r <= ur){
s[rt] = (r - l + 1) * k ;
tag[rt] = k ;
return ;
}
p_d(rt, l, r) ;
if (ul <= mid) update_C(ls(rt), l, mid, ul, ur, k) ;
if (ur > mid) update_C(rs(rt), mid + 1, r, ul, ur, k) ;
s[rt] = s[rs(rt)] + s[ls(rt)] ;
}
inline void qv(int now){
int ans = 0, dif = 0 ;
while (Top[now] != Top[1]){
ans += query_D(1, 1, N, Id[Top[now]], Id[now]) ;
dif += query_C(1, 1, N, Id[Top[now]], Id[now]) ;
now = fa[Top[now]] ;
}
ans += query_D(1, 1, N, 1, Id[now]) ;
dif += query_C(1, 1, N, 1, Id[now]) ;
printf("%d\n", ans - dif) ;
}
inline void uv(int now){
while (Top[now] != Top[1]){
update_C(1, 1, N, Id[Top[now]], Id[now], 1) ;
now = fa[Top[now]] ;
}
update_C(1, 1, N, 1, Id[now], 1) ;
}
int main(){
//freopen("manager.in", "r", stdin) ;
//freopen("manager.out", "w", stdout) ;
N = qrr() ;
fill (tag + 1, tag + (MAXN << 1) + 1, -1) ;
for (i = 2; i <= N ;i ++){
fa[i] = qrr() + 1,
sons[fa[i]].push_back(i) ;
} M = qrr() ;
_dfs1(1, 1, 0), _dfs2(1, 1), build(1, 1, N) ;
for (i = 1; i <= M ; i ++){
scanf("%s", in) ;
if (in[0] == 'u'){
In = qrr() + 1 ;
printf("%d\n", query_C(1, 1, N, Id[In], Id[In] + sub[In] - 1)) ;
update_C(1, 1, N, Id[In], Id[In]+ sub[In] - 1, 0) ;
continue ;
}
In = qrr() + 1 ;
qv(In), uv(In) ;
}
}

番外:以下是三次评测:

最快的是\(qread + printf + O2\),其次是\(qread + printf\),最慢的是\(qread + cout\)……

[题解向] Luogu2146[NOI2015]软件包管理器的更多相关文章

  1. 题解 P2146 【[NOI2015]软件包管理器】

    题目大意 ​ 给你一棵树, 求一点到根的路径上有多少个未标记点并全标记, 和询问一个点的子树内有多少已标记点和撤销标记 解题方法 1: install 操作 ​ 这个操作是求一点到根的路径上有多少个未 ...

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

    安装就把根节点到它全设为 1 删除就把以它为根的子树全设为 0 记得标记初始化为-1,因为标记是 0 的情况也是要处理的. #include <iostream> #include < ...

  3. 【题解】NOI2015软件包管理器

    [题解][P2146 NOI2015]软件包管理器 实际上就是树链剖分板子题. 对于\(install\)操作,直接查询它到\(0\)节点有多少已经安装了的,再用总数减去它. 对于\(uninstal ...

  4. 题解 P2146 [NOI2015]软件包管理器

    P2146 [NOI2015]软件包管理器 感觉代码比其他题解更简洁qwq 树链剖分模板题 install x:将1~x的路径上的节点全部变成1(安装x需要先安装1~x) uninstall x:将x ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Java之四大元注解@Target、@Retention、@Documented、@Inherited

    什么叫做元注解??   ==>用于注解[注释]的注解就叫做元注解 注解叫做:元数据,标签,注释           元注解[数据]--->注解--->标记代码 1.@Target : ...

  2. 浅浅的叙WPF之数据驱动与命令

    之前一直开发Winfrom程序,由于近一段时间转开发Wpf程序,刚好拜读刘铁锰<深入浅出WPF>对此有一些理解,如有误导指出,还望斧正!!! 说道WPF数据驱动的编程思想,MVVM,是为W ...

  3. chrome安装插件

    看了很多的解决办法,也试了很多种,有的有点用,有的只能用一次,最后成功了,在这里总结一下 一.首先下载 很多人下载的都ctx格式的,然后拖进去安装,用了一次就崩溃了,主要还是安装方式不对,一般需要将下 ...

  4. 如何在JIRA中有效使用关注和@提及 我正在关注的问题 提及我的问题 在仪表板上显示

    如何在JIRA中有效使用关注和@提及http://bbs.51testing.com/forum.php?mod=viewthread&tid=1157043&fromuid=1530 ...

  5. Python语言控制运算的优先级

    Python语言碰上计算式同时出现在一个指令内时,除了括号"(".")"最优外,其余计算优先次序如下: 次方(**). 乘法.除法.求余数(%).求整数(//) ...

  6. BZOJ3209: 花神的数论题(数位DP)

    题目: 3209: 花神的数论题 解析: 二进制的数位DP 因为\([1,n]\)中每一个数对应的二进制数是唯一的,我们枚举\(1\)的个数\(k\),计算有多少个数的二进制中有\(k\)个\(1\) ...

  7. Java自学-日期 日期格式化

    Java中使用SimpleDateFormat 进行日期格式化类 SimpleDateFormat 日期格式化类 示例 1 : 日期转字符串 y 代表年 M 代表月 d 代表日 H 代表24进制的小时 ...

  8. JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法)

    JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法) 一丶正则的用法 创建正则对象: 方式一: var reg=new ...

  9. js获取浏览器的缩放状态,浏览器右上角的百分比缩放后的状态

    首先说明,这里所说的浏览器状态是指用户点击浏览器左上角的放大加号/减号所产生的页面整体变大变小的情况(快捷键:Ctrl+加号或 Ctrl+减号 或 Ctrl+滚轮上下) 实现代码如下: detectZ ...

  10. mysql新加用户设置权限

    1.开通操作权限和表权限 GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON interface.* TO test1@'%' identif ...