【dfs序】【树状数组】bzoj1103 [POI2007]大都市meg

预处理出每个点到根节点的土路数,插到一个树状数组里,然后每次修改只会对子树中的节点造成影响,于是相当于区间修改、点查询了。

#include<cstdio>
using namespace std;
#define N 250001
int n,en,v[N<<1],next[N<<1],first[N],m;
void AddEdge(const int &U,const int &V)
{
	v[++en]=V;
	next[en]=first[U];
	first[U]=en;
}
int now,Ls[N],Rs[N],fa[N],a[N];
void dfs(int U)
{
	Ls[U]=++now;
	for(int i=first[U];i;i=next[i])
	  if(v[i]!=fa[U])
	    {
	      fa[v[i]]=U;
	      a[v[i]]=a[U]+1;
	      dfs(v[i]);
	    }
	Rs[U]=now;
}
int d[N];
void add_node(int p,const int &v){for(;p<=n;p+=(p&(-p)))d[p]+=v;}
void add_range(const int &L,const int &R,const int &v){add_node(L,v);if(R!=n)add_node(R+1,-v);}
int query(int p){int res=0;for(;p;p-=(p&(-p)))res+=d[p];return res;}
int main()
{
	int A,B; char op[2];
	scanf("%d",&n);
	for(int i=1;i<n;++i)
	  {
	  	scanf("%d%d",&A,&B);
	  	AddEdge(A,B);
	  	AddEdge(B,A);
	  }
	dfs(1);
	for(int i=2;i<=n;++i) add_range(Ls[i],Ls[i],a[i]);
	scanf("%d",&m);
	for(int i=1;i<n+m;++i)
	  {
	  	scanf("%s%d",op,&A);
	  	if(op[0]=='W') printf("%d\n",query(Ls[A]));
	  	else
	  	  {
	  	  	scanf("%d",&B);
	  	  	if(fa[A]==B) add_range(Ls[A],Rs[A],-1);
	  	  	else add_range(Ls[B],Rs[B],-1);
	  	  }
	  }
	return 0;
}
posted @ 2015-03-09 14:48  AutSky_JadeK  阅读(137)  评论(0编辑  收藏  举报
TVアニメ「Charlotte(シャーロット)」公式サイト TVアニメ「Charlotte(シャーロット)」公式サイト