1. 程式人生 > >CodeVS-蘋果樹

CodeVS-蘋果樹

highlight string set logs ios urn define mem 蘋果

好久沒寫博客了,也好久沒刷cv了,隨便寫篇爛文暖暖手吧...

這題是一道樹上的題目...求和一般我們會想到樹狀數組或者線段樹(藍鵝暴力我也茲瓷,只是覺得這時間好像會爆

一開始看題沒看仔細-->以為根節點不是1然後就開始煩惱,以為求一波重心(大霧

重心的求法聽czl講過,然後zzs說要用到什麽點分治邊分治(沒學,不懂,難打,棄坑

因為qzz過了這道題,所以開始抱大腿-->樹根是1啊...(論不看題。。。

於是知道了樹根我就直接想著用dfs序轉一下然後裸樹狀數組(沒想到過了。。。

技術分享

大概這樣...跑的還挺快的>_<

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<vector>
#include<map>
#include<algorithm>

using namespace std;

#define maxn 100010
#define ll long long
#define rep(i,l,r,step) for(int i=l;i<=r;i+=step)
#define down(i,l,r,step) for(int i=l;i>=r;i-=step)

int n,q,t[maxn],l[maxn],r[maxn],cnt; 
bool f[maxn];

//tree_array
#define lowbit(x) x&-x
int add(int x,int c){
	rep(i,x,n,lowbit(i))
		t[i]+=c;
}
int sum(int x){
	int ans=0;
	down(i,x,1,lowbit(i))
		ans+=t[i];
	return ans;
}

int edge,to[maxn*2],next[maxn*2],head[maxn];

//鄰接表
void insert(int u,int v){
	to[++edge]=v;
	next[edge]=head[u];
	head[u]=edge;
} 

//dfs序
void dfs(int rt,int fa){
	l[rt]=++cnt;
	add(l[rt],1);
	for(int i=head[rt];i;i=next[i]){
		if(to[i]!=fa) dfs(to[i],rt);
	}
	r[rt]=cnt;
} 

int main(){
	memset(f,1,sizeof(f));
	scanf("%d",&n);
	rep(i,1,n-1,1){
		int x,y;
		scanf("%d%d",&x,&y);
		insert(x,y);
		insert(y,x);
	}
	dfs(1,0);
	scanf("%d",&q);
	while(q--){
		char op[10];int x;
		scanf("%s%d",op,&x);
		if(op[0]==‘Q‘)
			printf("%d\n",sum(r[x])-sum(l[x]-1));
		else{
			if(f[x]){
				f[x]=0;add(l[x],-1);
			}
			else{
				f[x]=1;add(l[x],1);
			}
		}
	}
	return 0;
}

CodeVS-蘋果樹