题目大意:

  有n个软件安装包,除第一个以外,其他的要在另一个安装包的基础上安装,且无环,问在安装和卸载某个软件包时,这个操作实际上会改变多少个软件包的安装状态。

思路:

  可构成树,用树链剖分,线段树。已安装的为1,未安装的为0。对于安装操作,就是询问x到0的路径上0的个数,然后把这个路径赋为1;对于卸载操作,就是询问x的子树中1的个数,然后把子树赋为0。

代码:

 #include<cstdio>
#include<iostream>
#define M 800500
using namespace std; int n,cnt,dfn,hson[M],pa[M],id[M],to[M],top[M],vis[M],last[M],next[M],head[M],deep[M],size[M],sum[M],sz[M],lazy[M]; void ins(int x,int y)
{
to[++cnt]=y,next[cnt]=head[x],head[x]=cnt;
} void dfs1(int x)
{
size[x]=;
for (int i=head[x];i;i=next[i])
if (to[i]!=pa[x])
{
pa[to[i]]=x,deep[to[i]]=deep[x]+;
dfs1(to[i]),size[x]+=size[to[i]];
if (size[to[i]]>size[hson[x]]) hson[x]=to[i];
}
} void dfs2(int x,int tp)
{
id[x]=++dfn,top[x]=tp;
if (hson[x]) dfs2(hson[x],tp);
for (int i=head[x];i;i=next[i])
if (to[i]!=pa[x]&&to[i]!=hson[x]) dfs2(to[i],to[i]);
last[x]=dfn;
} void build(int l,int r,int cur)
{
if (l==r) { sum[cur]=,lazy[cur]=-,sz[cur]=; return; }
int mid=l+r>>;
build(l,mid,cur<<),build(mid+,r,cur<<|);
sz[cur]=sz[cur<<]+sz[cur<<|];
} void push_down(int k)
{
if (lazy[k]!=-)
{
sum[k<<]=sz[k<<]*lazy[k],sum[k<<|]=sz[k<<|]*lazy[k];
lazy[k<<]=lazy[k<<|]=lazy[k],lazy[k]=-;
}
} void change(int L,int R,int l,int r,int cur,int val)
{
if (L==l && R==r) { sum[cur]=val*sz[cur]; lazy[cur]=val; return; }
int mid=L+R>>; push_down(cur);
if (r<=mid) change(L,mid,l,r,cur<<,val);
else if (l>mid) change(mid+,R,l,r,cur<<|,val);
else change(L,mid,l,mid,cur<<,val),change(mid+,R,mid+,r,cur<<|,val);
sum[cur]=sum[cur<<]+sum[cur<<|];
} int ask(int L,int R,int l,int r,int cur)
{
if (L==l && R==r) return sum[cur];
int mid=L+R>>; push_down(cur);
if (r<=mid) return ask(L,mid,l,r,cur<<);
else if (l>mid) return ask(mid+,R,l,r,cur<<|);
else return ask(L,mid,l,mid,cur<<)+ask(mid+,R,mid+,r,cur<<|);
} void add(int x,int y)
{
if (deep[x]<deep[y]) swap(x,y);
int sum=,t=deep[x]-deep[y]+;
for (;top[x]!=top[y];x=pa[top[x]])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
sum+=ask(,n,id[top[x]],id[x],);
change(,n,id[top[x]],id[x],,);
}
if (deep[x]>deep[y]) swap(x,y);
sum+=ask(,n,id[x],id[y],);
change(,n,id[x],id[y],,);
printf("%d\n",t-sum);
} int main()
{
int i,m,x;
scanf("%d",&n);
for (i=;i<n;i++) scanf("%d",&m),ins(m+,i+);
scanf("%d",&m),dfs1(),dfs2(,),build(,n,);
for (i=;i<=m;i++)
{
char ch[];
scanf("%s%d",ch,&x),x++;
if (ch[]=='i') add(,x);
else printf("%d\n",ask(,n,id[x],last[x],)),change(,n,id[x],last[x],,);
}
return ;
}

[Noi2015]软件包管理器 题解的更多相关文章

  1. BZOJ4196:[NOI2015]软件包管理器——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=4196 https://www.luogu.org/problemnew/show/P2146 你决定 ...

  2. 洛谷P2146 [NOI2015]软件包管理器 题解 树链剖分+线段树

    题目链接:https://www.luogu.org/problem/P2146 本题涉及算法: 树链剖分: 线段树(区间更新及求和,涉及懒惰标记) 然后对于每次 install x ,需要将 x 到 ...

  3. 【题解】NOI2015软件包管理器

    [题解][P2146 NOI2015]软件包管理器 实际上就是树链剖分板子题. 对于\(install\)操作,直接查询它到\(0\)节点有多少已经安装了的,再用总数减去它. 对于\(uninstal ...

  4. 题解 P2146 [NOI2015]软件包管理器

    P2146 [NOI2015]软件包管理器 感觉代码比其他题解更简洁qwq 树链剖分模板题 install x:将1~x的路径上的节点全部变成1(安装x需要先安装1~x) uninstall x:将x ...

  5. Bzoj 4196: [Noi2015]软件包管理器 树链剖分

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 721  Solved: 419[Submit][Statu ...

  6. 【BZOJ4196】[Noi2015]软件包管理器 树链剖分

    [Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...

  7. [UOJ#128][BZOJ4196][Noi2015]软件包管理器

    [UOJ#128][BZOJ4196][Noi2015]软件包管理器 试题描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管 ...

  8. BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1352  Solved: 780[Submit][Stat ...

  9. [BZOJ4196][NOI2015]软件包管理器

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1040  Solved: 603[Submit][Stat ...

随机推荐

  1. codevs 1488GangGang的烦恼

    题目链接:http://codevs.cn/problem/1488/ 写个高精度大数运算就行 #include<cstdio> #include<iostream> #inc ...

  2. ViewPager部分源码分析三:scroll

    手指在屏幕上滑动,触发到onTouchEvent(),执行case MotionEvent.ACTION_MOVE: ... public boolean onTouchEvent(MotionEve ...

  3. 与你相遇好幸运,Linux常用命令

    开机挂载硬盘 cat  /etc/fstab /dev/sda1  /mnt/sda1 ext3    defaults    0  0 挂载硬盘 mount  /dev/sdb5 /home/dis ...

  4. ASP.NET MVC中Controller返回值类型ActionResult

    1.返回ViewResult视图结果,将视图呈现给网页 public class TestController : Controller { //必须存在Controller\Test\Index.c ...

  5. 【翻译二十】-java线程池

    Thread Pools Most of the executor implementations in java.util.concurrent use thread pools, which co ...

  6. gdo图形引擎中的旋转角

    横滚角(Roll) bank.roll  绕y轴 z轴正向为起点逆时针方向:往左为正,往右为负,水平时为0:有效范围:-180度-180度 注:下图是从飞机的尾部-->头部方向观察所得 俯仰角( ...

  7. [Spring Batch] 图解Spring Batch原理

    找到一副以前学习的图,稻清楚的描述了Spring Batch运行原理:  

  8. DTMF的原理分析

    转自:http://blog.csdn.net/wangwenwen/article/details/8264925 1. DTMF原理 DTMF(Double Tone MulitiFrequenc ...

  9. windows多线程详解

    转自:http://blog.csdn.net/zhouxuguang236/article/details/7775232 在一个牛人的博客上看到了这篇文章,所以就转过来了,地址是http://bl ...

  10. 基于ZigBee的家居控制系统的设计与应用

    基于ZigBee的家居控制系统的设计与应用 PPT简介:http://pan.baidu.com/s/1i38PC6D 摘  要 智能家居是未来家居的发展方向,其利用先进的网络技术.计算机技术和无线通 ...