【uoj128】 NOI2015—软件包管理器
来源:互联网 发布:软件的硬件要求 编辑:程序博客网 时间:2024/05/16 07:13
http://uoj.ac/problem/128 (题目链接)
题意:给出一棵树,每个节点代表一个软件包,维护卸载和安装操作。若要卸载节点x,那么必须卸载它的子树上的所有软件包;若要安装节点x必须安装所有它的祖先。每次询问安装或卸载某个软件包一共需要安装或者卸载多少个软件包。
Solution
很裸的树链剖分,0表示未安装,1表示已安装。安装操作很好处理对吧,每次对节点x到根节点这条路劲进行查询和修改即可。对于卸载操作,由于子树的dfs序是连续的,我们维护dfs序,进入x的子树时的时间戳L[x],退出时的时间戳R[x],查询和修改线段树上L[x]与R[x]之间的值即可。
不知为何UOJ上数组要开大2倍才能过。。
代码:
// uoj128#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#include<queue>#define MOD 1000000007#define inf 2147483640#define LL long long#define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);using namespace std;const int maxn=100010;struct tree {int l,r,s,tag;}tr[maxn<<1];struct edge {int to,next;}e[maxn<<1];int head[maxn],pos[maxn],size[maxn],deep[maxn],son[maxn],bl[maxn],bin[31],fa[maxn][31],L[maxn],R[maxn];int cnt,n,q,P;char s[maxn];void link(int u,int v) { e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt; e[++cnt].to=u;e[cnt].next=head[v];head[v]=cnt;}void build(int k,int s,int t) { tr[k]=(tree){s,t,0,-1}; if (s==t) return; int mid=(s+t)>>1; build(k<<1,s,mid); build(k<<1|1,mid+1,t);}void pushdown(int k) { int v=tr[k].tag; tr[k<<1].s=v*(tr[k<<1].r-tr[k<<1].l+1);tr[k<<1].tag=v; tr[k<<1|1].s=v*(tr[k<<1|1].r-tr[k<<1|1].l+1);tr[k<<1|1].tag=v; tr[k].tag=-1;}void update(int k,int s,int t,int v) { int l=tr[k].l,r=tr[k].r; if (l==s && r==t) {tr[k].s=v*(r-l+1);tr[k].tag=v;return;} if (tr[k].tag!=-1) pushdown(k); int mid=(l+r)>>1; if (t<=mid) update(k<<1,s,t,v); else if (s>mid) update(k<<1|1,s,t,v); else update(k<<1,s,mid,v),update(k<<1|1,mid+1,t,v); tr[k].s=tr[k<<1].s+tr[k<<1|1].s;}int query(int k,int s,int t) { int l=tr[k].l,r=tr[k].r; if (l==s && r==t) return tr[k].s; if (tr[k].tag!=-1) pushdown(k); int mid=(l+r)>>1; if (t<=mid) return query(k<<1,s,t); else if (s>mid) return query(k<<1|1,s,t); else return query(k<<1,s,mid)+query(k<<1|1,mid+1,t);}void dfs1(int x) { size[x]=1; for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa[x][0]) { deep[e[i].to]=deep[x]+1; fa[e[i].to][0]=x; dfs1(e[i].to); size[x]+=size[e[i].to]; if (size[e[i].to]>size[son[x]] || son[x]==0) son[x]=e[i].to; }}void dfs2(int x,int top) { L[x]=pos[x]=++P;bl[x]=top; if (son[x]) dfs2(son[x],top); for (int i=head[x];i;i=e[i].next) if (e[i].to!=son[x] && e[i].to!=fa[x][0]) dfs2(e[i].to,e[i].to); R[x]=P;}int solve(int x,int f) { int s=0; while (bl[x]!=bl[f]) { s+=query(1,pos[bl[x]],pos[x]); update(1,pos[bl[x]],pos[x],1); x=fa[bl[x]][0]; } if (pos[x]>=pos[f]) s+=query(1,pos[f],pos[x]),update(1,pos[f],pos[x],1); return s;}int main() { scanf("%d",&n); for (int x,i=1;i<n;i++) { scanf("%d",&x); link(i,x); } dfs1(0); dfs2(0,0); build(1,1,n); scanf("%d",&q); while (q--) { int x; scanf("%s%d",s,&x); if (s[0]=='i') { //int tmp=solve(x,0); printf("%d\n",deep[x]+1-solve(x,0)); } else { int tmp=query(1,L[x],R[x]); printf("%d\n",tmp); update(1,L[x],R[x],0); } } return 0;}
0 0
- 【uoj128】 NOI2015—软件包管理器
- uoj128/bzoj4196/NOI2015.软件包管理器(树链剖分)
- BZOJ4196——noi2015软件包管理器
- bzoj4196: [Noi2015]软件包管理器
- 【NOI2015】【BZOJ4196】软件包管理器
- 【NOI2015】【软件包管理器】【树链剖分】
- [BZOJ4196][Noi2015]软件包管理器
- bzoj4196[Noi2015]软件包管理器
- bzoj4196【NOI2015】软件包管理器
- bzoj4196软件包管理器 noi2015
- [BZOJ4196] [Noi2015]软件包管理器
- [题解][NOI2015]软件包管理器
- #128. 【NOI2015】软件包管理器
- 【NOI2015】BZOJ4196软件包管理器
- noi2015 d1t2 软件包管理器
- bzoj4196[NOI2015]软件包管理器
- bzoj4196: [NOI2015]软件包管理器
- NOI2015 软件包管理器 题解
- 自动收集机器负载结果的脚本(高性能mysql转载)
- 玲珑杯 1014 - Absolute Defeat
- 约瑟夫环简介,问题以及java实现
- Servlet基础
- NYOJ 题目2 括号配对问题(栈)(指针)
- 【uoj128】 NOI2015—软件包管理器
- Leetcode 407. Trapping Rain Water II 收集雨水2 解题报告
- MySQL Explain的使用
- OnPaint和OnDraw的区别
- RK3288 mipi 摄像头
- PHP Fatal error: Call to undefined function mysql_connect
- bbb上rtems的tcp/ip协议移植的想法
- java集合框架之Set------02_02 TreeSet
- Leetcode #258 Add Digits