BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)
时间:2019-03-26
本文章向大家介绍BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树),主要包括BZOJ - 4196 软件包管理器 (树链剖分+dfs序+线段树)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
设白色结点为未安装的软件,黑色结点为已安装的软件,则:
安装软件i:输出结点i到根的路径上的白色结点的数量,并把结点i到根的路径染成黑色。复杂度$O(nlog^2n)$
卸载软件i:输出结点i子树下的黑色结点数量,并把结点i的子树染成白色。复杂度$O(nlogn)$
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e5+10,inf=0x3f3f3f3f; 5 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<<2],mk[N<<2]; 6 struct E {int v,nxt;} e[N]; 7 void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;} 8 void dfs1(int u,int f,int d) { 9 fa[u]=f,son[u]=0,siz[u]=1,dep[u]=d; 10 for(int i=hd[u]; ~i; i=e[i].nxt) { 11 int v=e[i].v; 12 if(v==fa[u])continue; 13 dfs1(v,u,d+1),siz[u]+=siz[v]; 14 if(siz[v]>siz[son[u]])son[u]=v; 15 } 16 } 17 void dfs2(int u,int tp) { 18 top[u]=tp,dfn[u]=++tot,rnk[tot]=u; 19 if(son[u])dfs2(son[u],tp); 20 for(int i=hd[u]; ~i; i=e[i].nxt) { 21 int v=e[i].v; 22 if(v==fa[u]||v==son[u])continue; 23 dfs2(v,v); 24 } 25 ed[u]=tot; 26 } 27 #define ls (u<<1) 28 #define rs (u<<1|1) 29 #define mid ((l+r)>>1) 30 void pu(int u) {sum[u]=sum[ls]+sum[rs];} 31 void pd(int u,int l,int r) { 32 if(~mk[u]) { 33 sum[u]=mk[u]*(r-l+1); 34 if(l<r)mk[ls]=mk[rs]=mk[u]; 35 mk[u]=-1; 36 } 37 } 38 void upd(int L,int R,int x,int u=1,int l=1,int r=tot) { 39 pd(u,l,r); 40 if(l>=L&&r<=R) {mk[u]=x,pd(u,l,r); return;} 41 if(l>R||r<L)return; 42 upd(L,R,x,ls,l,mid),upd(L,R,x,rs,mid+1,r),pu(u); 43 } 44 int qry(int L,int R,int u=1,int l=1,int r=tot) { 45 pd(u,l,r); 46 if(l>=L&&r<=R)return sum[u]; 47 if(l>R||r<L)return 0; 48 return qry(L,R,ls,l,mid)+qry(L,R,rs,mid+1,r); 49 } 50 void changeroot(int u,int x) {for(; u; u=fa[top[u]])upd(dfn[top[u]],dfn[u],x);} 51 int askroot(int u) { 52 int ret=0; 53 for(; u; u=fa[top[u]])ret+=qry(dfn[top[u]],dfn[u]); 54 return ret; 55 } 56 void changesub(int u,int x) {upd(dfn[u],ed[u],x);} 57 int asksub(int u) {return qry(dfn[u],ed[u]);} 58 int main() { 59 memset(hd,-1,sizeof hd),ne=0; 60 scanf("%d",&n); 61 for(int i=2; i<=n; ++i) { 62 int u; 63 scanf("%d",&u),u++; 64 addedge(u,i); 65 } 66 tot=0,dfs1(1,0,1),dfs2(1,1); 67 memset(mk,-1,sizeof mk); 68 char s[10]; 69 scanf("%d",&m); 70 while(m--) { 71 int u; 72 scanf("%s%d",s,&u),u++; 73 if(s[0]=='i') { 74 printf("%d\n",dep[u]-askroot(u)); 75 changeroot(u,1); 76 } else { 77 printf("%d\n",asksub(u)); 78 changesub(u,0); 79 } 80 } 81 return 0; 82 }
- MYSQL5.7开启慢查询日志
- 微信又是一次大更新,下拉多任务切换 各种有趣小游戏
- 人工智能有可能超越人类大脑?
- 一种简单的数据库性能测试方法
- xiaomao.com7位数高价成交,并已启用建站
- Docker基于已有的镜像制新的镜像-Docker for Web Developers(3)
- 如何通过Remoting实现双向通信
- jenkins 入门教程(上)
- 让jQuery Tools Scrollable控件在Mobile Web里面支持resize功能
- CentOS6.5上golang环境配置
- 马斯克频发推文,或在揭示特斯拉明年大动作?
- yum安装出现No package nodejs available解决办法
- InfoPath中repeationg section动态填充数据
- CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- tensorflow 使用CPU而不使用GPU的问题解决
- Python图像灰度变换及图像数组操作
- 典型算法的Python实现
- Spring是如何解决循环依赖的
- Python将两个列表转换为字典
- 三、基于promise封装属于自己的Ajax库
- 数据分析 常见异常及解决办法(一)
- Python数据分析实战(2)使用Pandas进行数据分析
- 【redis】redis内存管理、淘汰机制、内存优化
- 如何防止网站被扒的解决方法!
- 【python-面试题53-循环排序】寻找缺失的数
- 【python-leetcode42-区间合并】区间列表的交集
- 【python-leetcode202-快慢指针】快乐数
- vuejs之结合使用vue+element-ui搭建后台管理页面
- 【python-leetcode142-快慢指针】环形链表2