BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)
设白色结点为未安装的软件,黑色结点为已安装的软件,则:
安装软件i:输出结点i到根的路径上的白色结点的数量,并把结点i到根的路径染成黑色。复杂度$O(nlog^2n)$
卸载软件i:输出结点i子树下的黑色结点数量,并把结点i的子树染成白色。复杂度$O(nlogn)$
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+,inf=0x3f3f3f3f;
int n,m,hd[N],ne,fa[N],son[N],siz[N],dep[N],top[N],dfn[N],rnk[N],ed[N],tot,sum[N<<],mk[N<<];
struct E {int v,nxt;} e[N];
void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
void dfs1(int u,int f,int d) {
fa[u]=f,son[u]=,siz[u]=,dep[u]=d;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u])continue;
dfs1(v,u,d+),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int tp) {
top[u]=tp,dfn[u]=++tot,rnk[tot]=u;
if(son[u])dfs2(son[u],tp);
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
ed[u]=tot;
}
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
void pu(int u) {sum[u]=sum[ls]+sum[rs];}
void pd(int u,int l,int r) {
if(~mk[u]) {
sum[u]=mk[u]*(r-l+);
if(l<r)mk[ls]=mk[rs]=mk[u];
mk[u]=-;
}
}
void upd(int L,int R,int x,int u=,int l=,int r=tot) {
pd(u,l,r);
if(l>=L&&r<=R) {mk[u]=x,pd(u,l,r); return;}
if(l>R||r<L)return;
upd(L,R,x,ls,l,mid),upd(L,R,x,rs,mid+,r),pu(u);
}
int qry(int L,int R,int u=,int l=,int r=tot) {
pd(u,l,r);
if(l>=L&&r<=R)return sum[u];
if(l>R||r<L)return ;
return qry(L,R,ls,l,mid)+qry(L,R,rs,mid+,r);
}
void changeroot(int u,int x) {for(; u; u=fa[top[u]])upd(dfn[top[u]],dfn[u],x);}
int askroot(int u) {
int ret=;
for(; u; u=fa[top[u]])ret+=qry(dfn[top[u]],dfn[u]);
return ret;
}
void changesub(int u,int x) {upd(dfn[u],ed[u],x);}
int asksub(int u) {return qry(dfn[u],ed[u]);}
int main() {
memset(hd,-,sizeof hd),ne=;
scanf("%d",&n);
for(int i=; i<=n; ++i) {
int u;
scanf("%d",&u),u++;
addedge(u,i);
}
tot=,dfs1(,,),dfs2(,);
memset(mk,-,sizeof mk);
char s[];
scanf("%d",&m);
while(m--) {
int u;
scanf("%s%d",s,&u),u++;
if(s[]=='i') {
printf("%d\n",dep[u]-askroot(u));
changeroot(u,);
} else {
printf("%d\n",asksub(u));
changesub(u,);
}
}
return ;
}
BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)的更多相关文章
- BZOJ_4034 [HAOI2015]树上操作 【树链剖分dfs序+线段树】
一 题目 [HAOI2015]树上操作 二 分析 树链剖分的题,这里主要用到了$dfs$序,这题比较简单的就是不用求$lca$. 1.和树链剖分一样,先用邻接链表建双向图. 2.跑两遍$dfs$,其实 ...
- BZOJ 2286 树链剖分+DFS序+虚树+树形DP
第一次学习虚树,就是把无关的点去掉.S里维护一条链即可. #include <iostream> #include <cstring> #include <cstdio& ...
- BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...
- BZOJ 2243:染色(树链剖分+区间合并线段树)
[SDOI2011]染色Description给定一棵有n个节点的无根树和m个操作,操作有2类:1.将节点a到节点b路径上所有点都染成颜色c:2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认 ...
- BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector
题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- POJ 2763 Housewife Wind 【树链剖分】+【线段树】
<题目链接> 题目大意: 给定一棵无向树,这棵树的有边权,这棵树的边的序号完全由输入边的序号决定.给你一个人的起点,进行两次操作: 一:该人从起点走到指定点,问你这段路径的边权总和是多少. ...
- 【XSY2667】摧毁图状树 贪心 堆 DFS序 线段树
题目大意 给你一棵有根树,有\(n\)个点.还有一个参数\(k\).你每次要删除一条长度为\(k\)(\(k\)个点)的祖先-后代链,问你最少几次删完.现在有\(q\)个询问,每次给你一个\(k\), ...
- BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1352 Solved: 780[Submit][Stat ...
随机推荐
- python之路 模块,序列化,迭代器,生成器
一.模块 1.模块简介 模块是一个包含所有你定义的函数和变量的文件,其后缀名是.py.模块可以被别的程序引入,以使用该模块中的函数等功能.这也是使用python标准库的方法. 类似于函数式编程和面向过 ...
- 【CodeChef】Turbo Sort
题目链接:Turbo Sort 用java自带O(NlogN)的排序就可以,java要特别注意输入输出.输入用BufferedReader,输出用printWriter.printWriter的速度比 ...
- js实现给一个数组监听
$.when.apply(null, table).done(callback); table=[]是个数组,用上$.when.apply就可以监听完成后执行callback 方法 callback就 ...
- PHP扩展模块Pecl、Pear以及Perl的区别
一.简短总结:pear:一个书写的比较规范,国外较流行的工具箱代码集pecl:php扩展包,但不属于php基本扩展范围perl:一种早于php出现的脚本级语言,php借鉴了他的正则表达式部分 二.Pe ...
- Qt开发UDP
一.单播 1.声明udp对象 QUdpSocket* udpClient: 2.new出对象 udpClient = new QUdpSocket(this); 3.分配本地地址(如果不分配,使用系统 ...
- [Android]开源中国源码分析之二---DrawerLayout
从启动界面到主界面之后的效果如图所示,采用的是v4包下的DrawerLayout, activity_main.xml文件如下: <!-- A DrawerLayout is intended ...
- Web项目java.lang.OutOfMemoryError: PermGen space异常解决
接手一个新的Web项目,编译运行(Tomcat版本为7),运行的时候报出了java.lang.OutOfMemoryError: PermGen space的异常,搜了一下这样解释: PermGe ...
- phpMyAdmin中config.inc.php设置密码和修改密码的方法
phpMyAdmin有3种授权模式: 1. cookie: 显示一个web登录页面,输入mysql的用户名和密码,然后进入管理界面. $cfg['Servers'][$i]['auth_type'] ...
- vue-router scrollBehavior无效的问题及解决方案
在使用vue做单页面应用开发时候 使用vue-router作为路由控制器 在使用过程中发现每个页面打开都在原来的位置 不能返回到页面顶部位置 ,然后查看api文档 滚动行为 发现如下代码: con ...
- winform获取文件路径
1.取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径 方法2.AppDomain.CurrentD ...