【NOI2015】软件包管理器(树链剖分)
来源:互联网 发布:c语言map容器 编辑:程序博客网 时间:2024/06/07 15:10
https://loj.ac/problem/2130
显然这道题是一个树状结构。
对于两种操作
设未安装为0,已安装为1
install x,相当于查询从0到x的路径中有多少个0,再将路径中的所有值置为1
uninstall x,相当于查询x的子树中有多少个1,再将子树中的所有值置为0
其实就是模板题,为了方便实现,我将0和1互换,这样的话install过程直接区间求和与区间修改。
而uninstall过程子树求和后再用子树的大小减去求得和,得到子树中0的个数。修改直接修改子树即可。
#include<bits/stdc++.h>#define fer(i,j,n) for(int i=j;i<=n;i++)#define far(i,j,n) for(int i=j;i>=n;i--)#define ll long long#define pa pair<int,int>const int maxn=1000010;const int INF=1e9+7;using namespace std;/*----------------------------------------------------------------------------*/inline ll read(){ char ls;ll x=0,sng=1; for(;ls<'0'||ls>'9';ls=getchar())if(ls=='-')sng=-1; for(;ls>='0'&&ls<='9';ls=getchar())x=x*10+ls-'0'; return x*sng;}/*----------------------------------------------------------------------------*/ll n,m; struct kaga{ int next; int point;}e[maxn];struct akagi{ int l,r; ll sum,lazy;}tr[maxn];int last[maxn],k=0,fa[maxn],size[maxn],son[maxn],belong[maxn],hashh[maxn],hashv[maxn],dep[maxn],v[maxn];void sumup(int x){ tr[x].sum=tr[x<<1].sum+tr[x<<1|1].sum; return ;}void pushdown(int x){ int y=tr[x].lazy; if(y==1) { tr[x<<1].lazy=1; tr[x<<1].sum=(tr[x<<1].r-tr[x<<1].l+1); tr[x<<1|1].lazy=1; tr[x<<1|1].sum=(tr[x<<1|1].r-tr[x<<1|1].l+1); } if(y==2) { tr[x<<1].lazy=2; tr[x<<1].sum=0; tr[x<<1|1].lazy=2; tr[x<<1|1].sum=0; } tr[x].lazy=0;}void build(int x,int l,int r){ int mid=(l+r)>>1; tr[x].l=l;tr[x].r=r; if(l==r) { tr[x].sum=1; tr[x].lazy=0; return ; } build(x<<1,l,mid); build(x<<1|1,mid+1,r); sumup(x); return ;}void change(int x,int L,int R,int val){ int l=tr[x].l,r=tr[x].r,mid=(l+r)>>1; if(L<=l&&r<=R) { if(val==1) { tr[x].sum=r-l+1; tr[x].lazy=1; } else if(val==2) { tr[x].sum=0; tr[x].lazy=2; } return ; } pushdown(x); if(R<=mid)change(x<<1,L,R,val); else if(L>mid)change(x<<1|1,L,R,val); else change(x<<1,L,mid,val),change(x<<1|1,mid+1,R,val); sumup(x); return ;}ll query(int x,int L,int R){ int l=tr[x].l,r=tr[x].r,mid=(l+r)>>1; if(L<=l&&r<=R)return tr[x].sum; pushdown(x); if(R<=mid)query(x<<1,L,R); else if(L>mid)query(x<<1|1,L,R); else return query(x<<1,L,mid)+query(x<<1|1,mid+1,R);}void add_edge(int x,int y){ e[++k].next=y;e[k].point=last[x];last[x]=k;}void insert(int x,int y){ add_edge(x,y); add_edge(y,x);}void dfs1(int x,int fat){ fa[x]=fat; dep[x]=dep[fat]+1; size[x]=1; for(int j=last[x];j;j=e[j].point) { int y=e[j].next; if(y==fat)continue; dfs1(y,x); size[x]+=size[y]; if(!son[x]||size[y]>size[son[x]]) son[x]=y; }}void dfs2(int x,int top){ belong[x]=top; hashh[x]=++k; hashv[k]=x; if(!son[x])return ; dfs2(son[x],top); for(int j=last[x];j;j=e[j].point) { int y=e[j].next; if(y!=son[x]&&y!=fa[x]) dfs2(y,y); }}void update(int x,int y,int val){ int topx=belong[x]; int topy=belong[y]; while(topx!=topy) { if(dep[topx]<dep[topy]) { swap(x,y); swap(topx,topy); } change(1,hashh[topx],hashh[x],val); x=fa[topx]; topx=belong[x]; } if(dep[x]>dep[y])swap(x,y); change(1,hashh[x],hashh[y],val);}ll sigma(int x,int y){ ll sum=0; int topx=belong[x]; int topy=belong[y]; while(topx!=topy) { if(dep[topx]<dep[topy]) { swap(x,y); swap(topx,topy); } sum+=query(1,hashh[topx],hashh[x]); x=fa[topx]; topx=belong[x]; } if(dep[x]>dep[y])swap(x,y); sum+=query(1,hashh[x],hashh[y]); return sum;}void updateson(int x,int val){ int left=hashh[x]; int right=hashh[x]+size[x]-1; change(1,left,right,val);}ll sigmason(int x){ int left=hashh[x]; int right=hashh[x]+size[x]-1; return right-left+1-query(1,left,right);}int main(){ n=read(); fer(i,2,n) { int x=read()+1; insert(x,i); } k=0; dfs1(1,0); dfs2(1,1); build(1,1,n); m=read(); fer(i,1,m) { char ls[10]; scanf("%s",ls); if(ls[0]=='i') { int x=read()+1; cout<<sigma(1,x)<<endl; update(1,x,2); } else { int x=read()+1; cout<<sigmason(x)<<endl; updateson(x,1); } }}
阅读全文
0 0
- [noi2015] 软件包管理器(树链剖分)
- 【NOI2015】软件包管理器(树链剖分)
- 【NOI2015】【软件包管理器】【树链剖分】
- 【bzoj4196】[Noi2015]软件包管理器 树链剖分
- Bzoj4196:[Noi2015]软件包管理器:树链剖分
- 【NOI2015】【bzoj4196】软件包管理器 树链剖分
- [bzoj4196][树链剖分][Noi2015]软件包管理器
- [bzoj4196][Noi2015]软件包管理器 树链剖分
- bzoj4196 [Noi2015]软件包管理器 树链剖分
- 【BZOJ4196】【NOI2015】软件包管理器(树链剖分,线段树)
- 【树链剖分+线段树】[noi2015]软件包管理器
- uoj128/bzoj4196/NOI2015.软件包管理器(树链剖分)
- 【BZOJ4196】[Noi2015]软件包管理器【树链剖分】【线段树】
- BZOJ_P4196 [NOI2015]软件包管理器(树链剖分+dfs序)
- noi2015 软件包管理器 树链剖分 + 线段树维护
- BZOJ 4196([Noi2015]软件包管理器-树链剖分)
- BZOJ 4196: [Noi2015]软件包管理器 树链剖分
- 洛谷 P2146 [NOI2015]软件包管理器 树链剖分
- 我的小工具-远程读卡器web客户端(nodejs+websocket实现实时指令交互)
- php 日期函数
- Java比较器-Comparable和Comparator
- EasyUI中 datagrid 插件 使用自定义的icon图标
- NAT穿透工具pwnat
- 【NOI2015】软件包管理器(树链剖分)
- 【云栖精选】当AI来敲门_一刊尽览人工智能
- iOS 单例模式的写法
- Java调用本地接口:java.lang.UnsatisfiedLinkError
- Android系统性能调优工具介绍
- PHP:const 和 defind 的区别
- 2017年校招全国统一模拟笔试(第二场)编程题集合--Python
- 解决 android audiorecord 蓝牙耳机 重启导致录音数据异常问题
- VS发布应用未能创建默认证书的问题解决方法