【bzoj4196】[Noi2015]软件包管理器
2016-03-29 22:18
281 查看
裸的树链剖分。
对于安装 查询和维护到根路径
对于卸载 查询和维护子树信息
一开始线段树add[]标记要全赋值为-1
对于安装 查询和维护到根路径
对于卸载 查询和维护子树信息
一开始线段树add[]标记要全赋值为-1
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef long long LL; #define N 200010 int id; int fa ,siz ,top ,son ; int pos ,r ; LL sum[N<<2],add[N<<2]; struct Node { int to,next; }e ; int head ; int cnt; int a; char s; int n,q; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } void link(int x,int y) { e[++cnt]=(Node){y,head[x]}; head[x]=cnt; } void dfs(int x) { siz[x]=1; for (int i=head[x],mx=0;i;i=e[i].next) if (e[i].to!=fa[x]) { fa[e[i].to]=x; dfs(e[i].to); siz[x]+=siz[e[i].to]; if (siz[e[i].to]>mx) mx=siz[e[i].to],son[x]=e[i].to; } } void dfs2(int x,int cha) { top[x]=cha; pos[x]=++id; if (son[x]) dfs2(son[x],cha); for (int i=head[x];i;i=e[i].next) if(e[i].to!=fa[x] && e[i].to!=son[x]) dfs2(e[i].to,e[i].to); r[x]=id; } void pushup(int now) { sum[now]=sum[now<<1]+sum[now<<1|1]; } void pushdown(int nowl,int nowr,int now,int mid) { if (add[now]!=-1) { LL t=add[now]; add[now]=-1; add[now<<1]=t; add[now<<1|1]=t; sum[now<<1]=t*(mid-nowl+1); sum[now<<1|1]=t*(nowr-mid); } } void update(int nowl,int nowr,int now,int s,int t,LL d) { if (nowl>=s && nowr<=t) { add[now]=d; sum[now]=(nowr-nowl+1)*d; return ; } int mid=(nowl+nowr)>>1; pushdown(nowl,nowr,now,mid); if (s<=mid) update(nowl,mid,now<<1,s,t,d); if (t>mid) update(mid+1,nowr,now<<1|1,s,t,d); pushup(now); } int query(int nowl,int nowr,int now,int s,int t) { if (nowl>=s && nowr<=t) return sum[now]; int mid=(nowl+nowr)>>1; int ans=0; pushdown(nowl,nowr,now,mid); if (s<=mid) ans+=query(nowl,mid,now<<1,s,t); if (t>mid) ans+=query(mid+1,nowr,now<<1|1,s,t); return ans; } int work1(int x) { int ans,res=0; while (x) { ans=query(1,n,1,pos[top[x]],pos[x]); res+=pos[x]-pos[top[x]]+1-ans; update(1,n,1,pos[top[x]],pos[x],1); if (ans) break; x=fa[top[x]]; } return res; } int work2(int x) { int res; res=query(1,n,1,pos[x],r[x]); update(1,n,1,pos[x],r[x],0); return res; } int main() { n=read(); for (int i=1;i<n;i++) { a=read(); link(a+1,i+1); } dfs(1); dfs2(1,1); memset(add,-1,sizeof(add)); q=read(); while (q--) { scanf("%c",&s); a=read(); if (s=='i') printf("%d\n",work1(a+1)); else printf("%d\n",work2(a+1)); } return 0; }
相关文章推荐
- 《Linux内核分析》第六周学习笔记
- 作业4
- 软件工程_4th weeks
- 《构建之法阅读笔记02》
- WordPress建站 新手入门
- gradle 基本配置介绍
- 第5周项目1(2)三角形类雏形
- Android 内存优化学习
- java中static的作用
- 欢迎使用CSDN-markdown编辑器
- Maven下构建bootstrap+jfinal项目Demo
- 微信高仿 视频
- Android studio 使用gradle 基础
- 图片高效加载
- 五大常用算法之三:贪心算法
- vue和Jquery差别之动态添加删除元素
- hdu1059 Dividing(多重背包+二进制优化)
- Java遇见HTML——JSP篇之商品浏览记录的实现
- Android应用经典主界面框架之一:仿QQ (使用Fragment, 附源码)
- JAVAEE 框架 2016-3-29