dfs 序 + 树状数组 poj 3321

dfs序:
很简单 很实用 很几把屌的一个东西,然而自己一直不会.
对树 进行 dfs 前序遍历, 那么对于 节点i ,F1[i]表示第一次出现的位置, F2[i]表示第二次出现的位置。 那么子树 就是 F1 –F2 之间的节点的和,即树状数组里面操作: query(F2[i]) - query (F1[i]-1) ,
poj 3321
题意: 给一颗树,n个节点,n-1条边。然后q次操作, 每次操作 Q 或者C +一个数pos, Q 代表询问 pos这个节点子树包含多少个节点, C 代表把pos 节点的的苹果 变为 0 或者 1 (如果原来有 变为0,否则变为1)

思想:
不仅仅是记录节点 个数啊,记录什么节点 权值,都能够做到啊


#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#define mem(a) memset(a,0,sizeof(a))
#define INF 0x7fffffff //INT_MAX
#define inf 0x3f3f3f3f //
const double PI = acos(-1.0);
const double e = exp(1.0);
template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
bool cmpbig(int a,int b){return a>b;}
bool cmpsmall(int a,int b){return a<b;}
using namespace std;

struct Edge{
    int to;
    int next;
};
Edge edge[200005];
int head[200005];
int tot,cnt;
int F1[200005],F2[200005];
void dfs(int u,int pre){
    F1[u]=++cnt;
    for(int i=head[u];i!=-1 ; i=edge[i].next){
        int v=edge[i].to;
        if(v==pre) continue;
        dfs(v,u);
    }
    F2[u]=cnt;
}
void addedge(int u,int v){
    edge[tot].to=v;
    edge[tot].next=head[u];
    head[u]=tot++;
}

struct segment{
    int l, r, i;
} A[200005];
int N;
int c[200005];

void add(int i, int v){
    for(; i<=N; i+=i&-i)
        c[i]+=v;     //
}
int sum(int x){
    int ret=0;
    for(; x>0; x-=x&-x)
        ret+=c[x];
    return ret;
}
int num[200005];
void init(){
    tot=0;
    cnt=0;
    memset(head,-1,sizeof(head));
    memset(num,0,sizeof(num));
}

int main()
{
   // freopen("1.txt","r",stdin);
    scanf("%d",&N);
         init();
         for(int i=1;i<N;i++){
             int a,b;
             scanf("%d %d",&a,&b);
             addedge(a,b);
             addedge(b,a);
         }
         dfs(1,1);
         for(int i=1;i<=N;i++){
             num[i]=1;
// printf("F1=%d\n",F1[i]);
             add(F1[i],1);  // 我们用F1 来 搞树状数组
         }
         int q;
         scanf("%d",&q);
         while(q--){
// printf("q=%d\n",q);
             char ch;int pos;
             getchar();
             scanf("%c %d",&ch,&pos);
// cout<<ch<<endl;
             if(ch=='Q'){
                 int ans;
                 ans= sum(F2[pos])-sum(F1[pos]-1);
                 printf("%d\n",ans);
             }
             else{
                 if(num[pos])
                     add(F1[pos],-1);
                 else
                     add(F1[pos],1);
                 num[pos]=1-num[pos];
             }
         }

    return 0;
}

你可能感兴趣的:(dfs 序 + 树状数组 poj 3321)