zoukankan      html  css  js  c++  java
  • luogu2146 [NOI2015]软件包管理器

    安装就把根节点到它全设为 1
    删除就把以它为根的子树全设为 0
    记得标记初始化为-1,因为标记是 0 的情况也是要处理的。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    int n, m, uu, hea[100005], cnt, dep[100005], fa[100005], son[100005], siz[100005];
    int top[100005], idx[100005], qwq;
    char ss[15];
    struct Edge{
    	int too, nxt;
    }edge[200005];
    struct SGT{
    	int sum[400005], tag[400005];
    	void build(int o, int l, int r){
    		tag[o] = -1;
    		if(l==r)	sum[o] = 0;
    		else{
    			int mid=(l+r)>>1;
    			int lson=o<<1;
    			int rson=lson|1;
    			if(l<=mid)	build(lson, l, mid);
    			if(mid<r)	build(rson, mid+1, r);
    			sum[o] = sum[lson] + sum[rson];
    		}
    	}
    	void pushDown(int o, int l, int r, int lson, int rson, int mid){
    		tag[lson] = tag[o];
    		tag[rson] = tag[o];
    		sum[lson] = (mid-l+1) * tag[o];
    		sum[rson] = (r-mid) * tag[o];
    		tag[o] = -1;
    	}
    	void update(int o, int l, int r, int x, int y, int k){
    		if(l>=x && r<=y){
    			sum[o] = (r-l+1) * k;
    			tag[o] = k;
    		}
    		else{
    			int mid=(l+r)>>1;
    			int lson=o<<1;
    			int rson=lson|1;
    			if(tag[o]!=-1)	pushDown(o, l, r, lson, rson, mid);
    			if(x<=mid)	update(lson, l, mid, x, y, k);
    			if(mid<y)	update(rson, mid+1, r, x, y, k);
    			sum[o] = sum[lson] + sum[rson];
    		}
    	}
    }sgt;
    void add_edge(int fro, int too){
    	edge[++cnt].nxt = hea[fro];
    	edge[cnt].too = too;
    	hea[fro] = cnt;
    }
    void dfs1(int x, int f){
    	dep[x] = dep[f] + 1;
    	fa[x] = f;
    	siz[x] = 1;
    	int maxSon=-1;
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(t!=f){
    			dfs1(t, x);
    			siz[x] += siz[t];
    			if(siz[t]>maxSon)	maxSon = siz[t], son[x] = t;
    		}
    	}
    }
    void dfs2(int x, int topf){
    	top[x] = topf;
    	idx[x] = ++qwq;
    	if(!son[x])	return ;
    	dfs2(son[x], topf);
    	for(int i=hea[x]; i; i=edge[i].nxt){
    		int t=edge[i].too;
    		if(t!=fa[x] && t!=son[x])
    			dfs2(t, t);
    	}
    }
    void upd(int xx, int yy){
    	while(top[xx]!=top[yy]){
    		if(dep[top[xx]]<dep[top[yy]])	swap(xx, yy);
    		sgt.update(1, 1, n, idx[top[xx]], idx[xx], 1);
    		xx = fa[top[xx]];
    	}
    	if(dep[xx]>dep[yy])	swap(xx, yy);
    	sgt.update(1, 1, n, idx[xx], idx[yy], 1);
    }
    int main(){
    	cin>>n;
    	for(int i=2; i<=n; i++){
    		scanf("%d", &uu);
    		add_edge(i, uu+1);
    		add_edge(uu+1, i);
    	}
    	dfs1(1, 0);
    	dfs2(1, 1);
    	sgt.build(1, 1, n);
    	cin>>m;
    	while(m--){
    		scanf("%s %d", ss, &uu);
    		uu++;
    		if(ss[0]=='i'){
    			int tmp=sgt.sum[1];
    			upd(1, uu);
    			printf("%d
    ", sgt.sum[1]-tmp);
    		}
    		else{
    			int tmp=sgt.sum[1];
    			sgt.update(1, 1, n, idx[uu], idx[uu]+siz[uu]-1, 0);
    			printf("%d
    ", tmp-sgt.sum[1]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    生成器函数
    初识函数
    格式化输出
    流程控制-while循环
    流程控制if语句
    Python入门
    Eclipse搭建C++开发环境
    Android SQLite基本用法
    Android拍照后更新相册
    操作系统相册和获取相册路径
  • 原文地址:https://www.cnblogs.com/poorpool/p/8289963.html
Copyright © 2011-2022 走看看