Segment Tree Summary (Topic Collection)

1,POJ - 3321

Topic: Give an apple tree, each node has an apple at the beginning. C X, if there is an apple at point X, remove it, and if not, grow a new one. Q X, query X point and all its offspring branch a total of several apples.

Analysis: Use dfs order to transform sub-tree nodes into continuous intervals, and then use segment tree for single point modification and interval summation. Note that vector < int > G [N] will overtime, just change to vector < vector < int > G.

Code:

#include<cstdio>
#include<vector>
#include<cstdlib>
using namespace std;
const int N = 1e5+5;
int n,m;
int cnt,s[N],e[N];
/// vector < int > G [N]; (timeout)
vector<vector<int> > g(N);

void dfs(int fa,int x) {
    s[x]=++cnt;
    for(int i=0;i<g[x].size();i++) {
        int u=g[x][i];
        if(u!=fa) dfs(x,u);
    }
    e[x]=cnt;
}

int sum[4*N];
void bd(int o,int l,int r) {
    if(l==r) {
        sum[o]=1;
        return ;
    }
    int m=(l+r)/2;
    bd(2*o,l,m);
    bd(2*o+1,m+1,r);
    sum[o]=sum[2*o]+sum[2*o+1];
}

void up(int o,int l,int r,int x) {
    if(l==r) {
        sum[o]=1-sum[o];
        return ;
    }
    int m=(l+r)/2;
    if(x<=m) up(2*o,l,m,x);
    else up(2*o+1,m+1,r,x);
    sum[o]=sum[2*o]+sum[2*o+1];
}

int qu(int o,int l,int r,int ql,int qr) {
    if(ql<=l&&qr>=r) return sum[o];
    int m=(l+r)/2;
    if(qr<=m) return qu(2*o,l,m,ql,qr);
    else if(ql>m) return qu(2*o+1,m+1,r,ql,qr);
    else return qu(2*o,l,m,ql,qr)+qu(2*o+1,m+1,r,ql,qr);
}

int main() {
    scanf("%d",&n);
    for(int i=1;i<n;i++) {
        int u,v;
        scanf("%d%d",&u,&v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(-1,1);
    bd(1,1,cnt);
    scanf("%d",&m);
    while(m--) {
        char op;
        int x;
        scanf(" %c%d",&op,&x);
        if(op=='C') up(1,1,cnt,s[x]);
        else printf("%d\n",qu(1,1,cnt,s[x],e[x]));
    }
    return 0;
}

 

Posted by steveness on Fri, 04 Oct 2019 10:18:33 -0700