社区讨论

树剖 10pts 求调玄关

P2146[NOI2015] 软件包管理器参与者 1已保存回复 0

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
0 条
当前快照
1 份
快照标识符
@mhjta19f
此快照首次捕获于
2025/11/04 08:09
4 个月前
此快照最后确认于
2025/11/04 08:09
4 个月前
查看原帖
rt
CPP
#include <bits/stdc++.h>
#include <bits/extc++.h>
using namespace std;
using namespace __gnu_pbds;
#define endl '\n' 
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define un unsigned
#define ls u<<1
#define rs u<<1|1


typedef long long LL;
// #define int LL
const int _=100010;

int n,m,r;
int dep[_],siz[_],fa[_],son[_],id[_],wt[_],top[_];
int segt[_],a[_<<2],lzy[_<<2];
int cnt;
vector<int> tu[_];

void dfs1(int x,int f,int deep){
	dep[x]=deep;
	fa[x]=f;
	siz[x]=1;
	int maxs=-1;
	for(int y:tu[x]){
		if(y==f) continue;
		dfs1(y,x,deep+1);
		siz[x]+=siz[y];
		if(siz[y]>maxs){
			son[x]=y;
			maxs=siz[y];
		}
		// siz[son[x]]>siz[y]?son[x]=y:1;
	}
}

void dfs2(int x,int topf){
	id[x]=++cnt;
	wt[cnt]=segt[x];
	top[x]=topf;
	if(!son[x]) return;
	dfs2(son[x],topf);
	for(int y:tu[x]){
		if(y==fa[x]||y==son[x]) continue;
		dfs2(y,y);
	}
}

void pushup(int u){a[u]=(a[ls]+a[rs]);}

void mtag(int u,int len,int x){
	lzy[u]=x;
	a[u]=(len*x);
}

void pushdown(int u,int l,int r){
	int mid=(l+r)>>1;
	if(lzy[u]!=lzy[0]){
		mtag(ls,mid-l+1,lzy[u]);
		mtag(rs,r-mid,lzy[u]);
		lzy[u]=lzy[0];
	}
}

void bt(int u,int l,int r){
	if(l==r){
		a[u]=wt[l];
		return;
	}
	int mid=(l+r)>>1;
	bt(ls,l,mid);
	bt(rs,mid+1,r);
	pushup(u);
}

void upd(int u,int l,int r,int p,int x){
	if(l==r) a[u]=x;
	else{
		int mid=(l+r)>>1;
		if(mid>=p) upd(ls,l,mid,p,x);
		else upd(rs,mid+1,r,p,x);
		pushup(u);
	}
}

bool inr(int L,int R,int l,int r){//[l,r]被[L,R]包含
	return (l<=L)&&(r>=R);
}

bool outr(int l,int r,int L,int R){//[l,r]与[L,R]完全无交集
	return (L>r)||(R<l);
}

int rque(int u,int L,int R,int l,int r){//区间查询
	if(inr(L,R,l,r)) return a[u];
	else if(!outr(L,R,l,r)){
		int mid=(L+R)>>1;
		
		return (rque(ls,L,mid,l,r)+rque(rs,mid+1,R,l,r));
	}
	else return 0;
}

void rupd(int u,int L,int R,int l,int r,int x){//区间修改
	if(inr(L,R,l,r)) mtag(u,R-L+1,x);
	else if(!outr(L,R,l,r)){
		int mid=(L+R)>>1;
		pushdown(u,L,R);
		rupd(ls,L,mid,l,r,x);
		rupd(rs,mid+1,R,l,r,x);
		pushup(u);
	}
}

// ------------------------------------------------------------------- //

int pque(int x,int y){//结点最短路径上所有节点的值之和
	int ans=0;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans+=rque(1,1,n,id[top[x]],id[x]);
		x=fa[top[x]];
	}
	if(id[x]>id[y]) swap(x,y);
	ans+=rque(1,1,n,id[x],id[y]);
	return ans;
}

void pupd(int x,int y,int k){//结点最短路径上所有节点的值+k
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		rupd(1,1,n,id[top[x]],id[x],k);
		x=fa[top[x]];
	}
	if(id[y]<id[x]) swap(x,y);
	rupd(1,1,n,id[x],id[y],k);
}

int sque(int x){
	return rque(1,1,n,id[x],id[x]+siz[x]-1);
}

void supd(int x,int k){
	rupd(1,1,n,id[x],id[x]+siz[x]-1,k);
}

signed main(){
	int A;
	memset(lzy,63,sizeof(lzy));
	ios::sync_with_stdio(false);
	cin>>n;
	for(int i=2,A;i<=n;i++){
		cin>>A;A++;
		tu[A].pb(i);tu[i].pb(A);
	}
	
	dfs1(1,0,1);
	dfs2(1,1);
	
	bt(1,1,n);
	
	int T;cin>>T;
	string op;
	while(T--){
		cin>>op>>A;A++;
		if(op=="install"){
			int tmp=rque(1,1,n,1,n);
			
			pupd(A,1,1);
			// cerr<<"   p   "<<tmp<<" "<<rque(1,1,n,1,n)<<endl;
			cout<<abs(tmp-rque(1,1,n,1,n))<<endl;
		}
		else{
			int tmp=sque(id[A]);
			
			supd(id[A],0);
			// cerr<<"   s   "<<tmp<<" "<<sque(id[A])<<endl;
			cout<<abs(tmp-sque(id[A]))<<endl;
			
		}
	}
	
	return 0;
}

// o(*≧▽≦)ツ┏━┓ QAQ awa awa qwq QwQ
// Ciallo~(∠・ω< )⌒★
///////////////////////
//       furry       //
///////////////////////
/*
world.excute(me);
Infinite Strife,
Aether Crest:Astral
Abstruse Dilemma
Regnaissance
*/

回复

0 条回复,欢迎继续交流。

正在加载回复...