bzoj4196: [Noi2015]软件包管理器

来源:互联网 发布:mac照片拷到移动硬盘 编辑:程序博客网 时间:2024/05/29 07:07

题目

  http://www.lydsy.com/JudgeOnline/problem.php?id=4196

题解

  不知为啥,NOI的题就是感觉清新。。

  install就是把这个点到根节点的链上的权值赋成1,uninstall就是删除子树(dfs序)。每次查询整棵子树,和上次的查询取个差的绝对值输出。

代码

//树链剖分+线段树#include <cstdio>#include <algorithm>#include <iostream>#define maxn 100010using namespace std;struct segtree{int l, r, sum, set;segtree *lch, *rch;segtree(){sum=0;set=-1;lch=rch=0;}}*root;int N, head[maxn], next[maxn], to[maxn], fa[maxn], tid[maxn], top[maxn], son[maxn],size[maxn], tot, tim, l[maxn], r[maxn], deep[maxn];void adde(int a, int b){to[++tot]=b;next[tot]=head[a];head[a]=tot;}void input(){int i;scanf("%d",&N);fa[0]=-1;for(i=1;i<N;i++){scanf("%d",fa+i);adde(fa[i],i);}}void pushdown(segtree *p){if(p->set!=-1){p->sum=p->set*(p->r-p->l+1);if(p->lch)p->lch->set=p->rch->set=p->set;p->set=-1;}}void update(segtree *p){if(p->lch==0)return;pushdown(p->lch),pushdown(p->rch);p->sum=p->lch->sum+p->rch->sum;}void build(segtree *p, int l, int r){int mid=(l+r)>>1;p->l=l,p->r=r;if(l==r)return;build(p->lch=new segtree,l,mid);build(p->rch=new segtree,mid+1,r);}void segset(segtree *p, int l, int r, int w){pushdown(p);int mid=(p->l+p->r)>>1;if(l<=p->l and r>=p->r){p->set=w;return;}if(l<=mid)segset(p->lch,l,r,w);if(r>mid)segset(p->rch,l,r,w);update(p);}int segsum(segtree *p, int l, int r){pushdown(p);int mid=(l+r)>>1, ans=0;if(l<=p->l and r>=p->r){return p->sum;}if(l<=mid)ans+=segsum(p->lch,l,mid);if(r>mid)ans+=segsum(p->rch,mid+1,r);return ans;}void dfs1(int pos){int p;size[pos]=1;for(p=head[pos];p;p=next[p]){if(to[p]==fa[pos])continue;deep[to[p]]=deep[pos]+1;dfs1(to[p]);if(son[pos]==0 or size[to[p]]>size[son[pos]])son[pos]=to[p];size[pos]+=size[to[p]];}}void dfs2(int pos, int tp){int p;top[pos]=tp;tid[pos]=++tim;l[pos]=tim;if(son[pos])dfs2(son[pos],tp);for(p=head[pos];p;p=next[p]){if(to[p]==fa[pos] or to[p]==son[pos])continue;dfs2(to[p],to[p]);}r[pos]=tim;}void install(int x){while(x!=-1)segset(root,tid[top[x]],tid[x],1),x=fa[top[x]];}int main(){int i, x, q, last=0;char type[100];input();dfs1(0);dfs2(0,0);build(root=new segtree,1,tim);scanf("%d",&q);for(i=1;i<=q;i++){scanf("%s%d",type,&x);if(*type=='i')install(x);else segset(root,l[x],r[x],0);x=segsum(root,1,tim);printf("%d\n",abs(x-last));last=x;}return 0;}


0 0
原创粉丝点击