zoukankan      html  css  js  c++  java
  • 【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
    ",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;
    }
  • 相关阅读:

    暴力求解/数学问题
    Leetcode207. Course Schedule
    Balanced Team
    由先序和中序求后序
    Median String
    树的同构
    uva 202
    整除光棍
    阅览室
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/4323581.html
Copyright © 2011-2022 走看看