• LOJ 2130 软件包管理器


    熟练剖分

    路径到根直接向上跳

    #include <iostream>
    #include <cassert>
    #include <string>
    
    using namespace std;
    
    const int MAXN=101111;
    
    int N, M;
    int P;
    string com;
    
    struct Vert{
    	int Fa, Son, Bro;
    	int Size, Dep;
    	int MainSon, Top;
    	int Dps, Dpr;
    } V[MAXN];
    
    void DFS1(int at){
    	V[at].Size=1;
    	for(int to=V[at].Son;to>0;to=V[to].Bro){
    		V[to].Dep=V[at].Dep+1;
    		DFS1(to);
    		V[at].Size+=V[to].Size;
    		if(V[at].MainSon<=0 || V[to].Size>V[V[at].MainSon].Size)	V[at].MainSon=to;
    	}
    }
    
    int Dfn[MAXN], DFN;
    
    void DFS2(int at, int t){
    	++DFN;
    	Dfn[DFN]=at;V[at].Dps=DFN;
    	V[at].Top=t;
    	if(V[at].MainSon>0)	DFS2(V[at].MainSon, t);
    	for(int to=V[at].Son;to>0;to=V[to].Bro){
    		if(to==V[at].MainSon)	continue;
    		DFS2(to, to);
    	}
    	V[at].Dpr=DFN;/**/
    }
    
    struct Node{
    	int l, r;
    	int Sum;
    	int opt;
    } T[MAXN<<2];
    
    int L, R, op;
    int Sum;
    
    void BuildTree(int l, int r, int at){
    	T[at].l=l;T[at].r=r;T[at].Sum=0;T[at].opt=-1;
    	if(l<r){
    		int m=(l+r)>>1;
    		BuildTree(l, m, at<<1);
    		BuildTree(m+1, r, (at<<1)|1);
    	}
    }
    
    void opr(int at){
    	T[at].Sum=op*(T[at].r-T[at].l+1);
    }
    
    void cop(int at){
    	T[at].opt=op;
    }
    
    void pdw(int at){
    	if(T[at].opt==-1)	return;
    	int top=op;op=T[at].opt;
    	opr(at<<1);cop(at<<1);
    	opr((at<<1)|1);cop((at<<1)|1);
    	op=top;T[at].opt=-1;
    }
    
    void pup(int at){
    	T[at].Sum=T[at<<1].Sum+T[(at<<1)|1].Sum;
    }
    
    int Ask(int at){
    	if(T[at].l>=L && T[at].r<=R){
    		return T[at].Sum;
    	}
    	pdw(at);
    	int m=(T[at].l+T[at].r)>>1;
    	int ret=0;
    	if(L<=m)	ret+=Ask(at<<1);
    	if(R>m)	ret+=Ask((at<<1)|1);
    	return ret;
    }
    
    void Update(int at){
    	if(T[at].l>=L && T[at].r<=R){
    		T[at].Sum=op*(T[at].r-T[at].l+1);
    		T[at].opt=op;
    		return;
    	}
    	pdw(at);
    	int m=(T[at].l+T[at].r)>>1;
    	if(L<=m)	Update(at<<1);
    	if(R>m)	Update((at<<1)|1);
    	pup(at);
    }
    
    int main(){
    	ios_base::sync_with_stdio(false);
    	
    	cin >> N;
    	for(int i=2, f;i<=N;++i){
    		cin >> f;++f;
    		V[i].Fa=f;V[i].Bro=V[f].Son;V[f].Son=i;
    	}
    	
    	V[1].Dep=1;
    	DFS1(1);
    	DFS2(1, 1);
    	
    	assert(DFN==N);
    	BuildTree(1, N, 1);
    	
    	cin >> M;
    	while(M--){
    		cin >> com >> P;++P;
    		Sum=0;
    		if(com[0]=='i'){
    			op=1;
    			for(int k=P;k>0;k=V[V[k].Top].Fa){
    				L=V[V[k].Top].Dps;R=V[k].Dps;
    				Sum+=Ask(1);
    				Update(1);
    			}
    			cout << V[P].Dep-Sum << endl;
    		}
    		else{
    			op=0;
    			L=V[P].Dps;R=V[P].Dpr;
    			Sum=Ask(1);
    			Update(1);
    			cout << Sum << endl;
    		}
    	}
    	
    	return 0;
    }
    
  • 相关阅读:
    如何配置透明发光的骚气 vscode —— Jinkey 原创
    JS引用类型总结
    element UI -- 默认样式修改不成功原因
    上传本地Vue项目到github
    网页加载速度优化方法总结
    移动端click时间、touch事件、tap事件详解
    移动端开发用touch事件还是click事件
    禁止网站调用favicon.ico请求
    HTTP里面的响应和请求
    jave script 中this的指向 (六种场景)
  • 原文地址:https://www.cnblogs.com/Pickupwin/p/9094146.html
Copyright © 2020-2023  润新知