码迷,mamicode.com
首页 > 其他好文 > 详细

【NOI2015】软件包管理器

时间:2017-04-01 23:07:44      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:依赖   分享   return   tree   div   多少   for   依赖关系   can   

Description

你决定设计你自己的软件包管理器。不可避免的,你要解决软件包之间的依赖关系。如果A依赖B,那么安装A之前需安装B,卸载B之前须卸载A。0号软件包不依赖任何软件包。依赖关系不存在环(包括自环)。
你的任务是,求出每次安装、删除操作会改变多少个包的状态。
安装一个已安装的软件包,或者卸载一个未安装的软件包,都不会改变任何软件包的安装状态,即在此情况下,改变安装状态的软件包数为0
每次操作不仅需要计算安装软件包数,还作为操作影响后来的安装/删除

Input

第一行一个整数n,表示软件包的总数。
随后n-1个整数a1,a2,...an-1,表示第i个软件包依赖第ai个软件包
接下来一行一个整数q,表示询问数
之后q行,每行一个询问,询问分为两种
install x:表示安装x
uninstall x:表示卸载x

Output

q行,每行一个整数,为第i步操作改变安装状态的软件包数

Sample Input

样例输入1:
7
0 0 0 1 1 5
5
install 5
install 6
uninstall 1
install 4
uninstall 0

样例输入2:
10
0 1 2 1 3 0 0 3 2
10
install 0
install 3
uninstall 2
install 7
install 5
install 9
uninstall 9
install 4
install 1
install 9

Sample Output

样例输出1:
3
1
3
2
3
样例输出2:
1
3
2
1
3
1
1
1
0
1

Hint

样例输入1说明:

技术分享

一开始所有的软件包都处于未安装状态。
安装5号软件包,需安装0,1,5三个软件包
之后安装6号软件包,只需安装6号软件包。此时安装了0,1,5,6四个软件包。
卸载1号软件包需要卸载1,5,6三个软件包,此时只有0号软件包还处于安装状态
之后安装4号软件包,需安装1,4两个软件包。此时0,1,4处于安装状态
最后,卸载0号软件包会卸载所有的软件包

数据提示:
1,2:n=5000 q=5000
3,4:n=100000 q=100000 没有卸载操作
5,6,7,8 n=100000,q=100000 依赖关系和操作随机
9-20 n=100000,q=100000 不随机

Source

NOI2015 Day1 T2
树链剖分

思路{
  树链剖分题。
  安装和非安装可看成0,1串,查询区间和即可
}
  1 #include<algorithm>
  2 
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<vector>
  7 #include<queue>
  8 #include<ctime>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 #define MAXX 1000010
 13 #define rs ((o<<1)|1)
 14 #define ls (o<<1)
 15 #define mid ((l+r)>>1)
 16 using namespace std;
 17 struct ed{
 18   int nxt,to;
 19 }e[MAXX*2];
 20 int tot,sum,n,m,q,lazy[MAXX*4],x;
 21 char a[50];
 22 int tree[MAXX*4],deep[MAXX],siz[MAXX+10],hson[MAXX],head[MAXX],top[MAXX],id[MAXX],fa[MAXX],tt[MAXX];
 23 void addd(int u,int v){e[tot].nxt=head[u],e[tot].to=v,head[u]=tot++;}
 24 void ADD(int u,int v){addd(u,v),addd(v,u);}
 25 void dfs1(int u,int faa){
 26   fa[u]=faa,deep[u]=deep[faa]+1,siz[u]=1;
 27   for(int i=head[u];i!=-1;i=e[i].nxt)if(e[i].to!=faa){
 28       int v=e[i].to;dfs1(v,u);
 29       siz[u]+=siz[v];
 30       if(siz[hson[u]]<siz[v]||!hson[u])hson[u]=v;
 31     }
 32 }
 33 void dfs2(int u,int toop){
 34   id[u]=++sum;top[u]=toop;if(hson[u]!=MAXX+8)dfs2(hson[u],toop);
 35   for(int i=head[u];i!=-1;i=e[i].nxt)if(e[i].to!=hson[u]&&e[i].to!=fa[u])dfs2(e[i].to,e[i].to);
 36   tt[u]=sum;
 37 }
 38 void down(int o,int l,int r){
 39   if(!lazy[o])return;
 40   if(lazy[o]==1)tree[ls]=(mid-l+1),tree[rs]=(r-mid);
 41   else if(lazy[o]==-1)tree[ls]=tree[rs]=0;
 42   lazy[rs]=lazy[ls]=lazy[o];lazy[o]=0;
 43 }
 44 int ask(int o,int l,int r,int ll,int rr){
 45   if(l!=r)down(o,l,r);
 46   if(l>=ll&&r<=rr)return tree[o];
 47   if(mid<ll)return ask(rs,mid+1,r,ll,rr);
 48   else if(mid>=rr)return ask(ls,l,mid,ll,rr);
 49   else return ask(rs,mid+1,r,ll,rr)+ask(ls,l,mid,ll,rr);
 50 }
 51 void change(int o,int l,int r,int ll,int rr){
 52   if(l!=r)down(o,l,r);
 53   if(l>=ll&&r<=rr){tree[o]=r-l+1;lazy[o]=1;return;}
 54   if(mid<ll)change(rs,mid+1,r,ll,rr);
 55   else if(mid>=rr)change(ls,l,mid,ll,rr);
 56   else change(rs,mid+1,r,ll,rr),change(ls,l,mid,ll,rr);
 57   tree[o]=tree[rs]+tree[ls];
 58 }
 59 int lca(int x,int y){
 60   int sum=0;
 61   while(top[x]!=top[y]){
 62     if(deep[top[x]]<deep[top[y]])swap(x,y);
 63     sum+=id[x]-id[top[x]]-ask(1,1,n,id[top[x]],id[x])+1;
 64     change(1,1,n,id[top[x]],id[x]);
 65     x=fa[top[x]];
 66   }
 67   if(deep[x]>deep[y])swap(x,y);
 68   sum+=id[y]-id[x]+1-ask(1,1,n,id[x],id[y]);
 69   change(1,1,n,id[x],id[y]);
 70   return sum;
 71 }
 72 int ask1(int o,int l,int r,int ll,int rr){
 73   if(l!=r)down(o,l,r);
 74   if(l>=ll&&r<=rr)return tree[o];
 75   if(mid<ll)return ask1(rs,mid+1,r,ll,rr);
 76   else if(mid>=rr)return ask1(ls,l,mid,ll,rr);
 77   else return ask1(rs,mid+1,r,ll,rr)+ask1(ls,l,mid,ll,rr);
 78 }
 79 void chage(int o,int l,int r,int ll,int rr){
 80   if(l!=r)down(o,l,r);
 81   if(l>=ll&&r<=rr){
 82     tree[o]=0;lazy[o]=-1;return;
 83   }if(mid<ll)chage(rs,mid+1,r,ll,rr);
 84   else if(mid>=rr)chage(ls,l,mid,ll,rr);
 85   else chage(rs,mid+1,r,ll,rr),chage(ls,l,mid,ll,rr);
 86   tree[o]=tree[ls]+tree[rs];
 87 }
 88 int main(){
 89   memset(head,-1,sizeof(head));
 90   scanf("%d",&n);for(int i=1;i<=n;++i)hson[i]=MAXX+8;
 91   for(int i=1;i<n;++i){int v;scanf("%d",&v);ADD(i,v);}
 92   dfs1(0,0),dfs2(0,0);
 93   scanf("%d",&q);
 94   for(int i=1;i<=q;++i){
 95     scanf("%s",a);scanf("%d",&x);
 96     if(a[0]==i)printf("%d\n",lca(0,x));
 97     else {
 98       printf("%d\n",ask1(1,1,n,id[x],tt[x]));
 99       chage(1,1,n,id[x],tt[x]);
100     }
101   }
102   return 0;
103 }

 

【NOI2015】软件包管理器

标签:依赖   分享   return   tree   div   多少   for   依赖关系   can   

原文地址:http://www.cnblogs.com/zzmmm/p/6657636.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!