zoj 3686 线段树

A Simple Tree Problem

Time Limit: 3 Seconds      Memory Limit: 65536 KB

Given a rooted tree, each node has a boolean (0 or 1) labeled on it. Initially, all the labels are 0.

We define this kind of operation: given a subtree, negate all its labels.

And we want to query the numbers of 1's of a subtree.

Input

Multiple test cases.

First line, two integer N and M, denoting the numbers of nodes and numbers of operations and queries.(1<=N<=100000, 1<=M<=10000)

Then a line with N-1 integers, denoting the parent of node 2..N. Root is node 1.

Then M lines, each line are in the format "o node" or "q node", denoting we want to operate or query on the subtree with root of a certain node.

Output

For each query, output an integer in a line.

Output a blank line after each test case.

Sample Input

3 2
1 1
o 2
q 1

Sample Output

1


Author: CUI, Tianyi
Contest: ZOJ Monthly, March 2013

先先序遍历 + 后序遍历把子树转为同一个区间内,然后线段树即可。

#include<iostream>
#include<cstdio>
#include<vector>


using namespace std;

#define LL long long
#define lson (p->lch)
#define rson (p->rch)
#define MAXN 111111

int n, m;
vector<int> g[MAXN];

struct node{
    int l, r, num, todo;
    node *lch, *rch;
}*root;

int tsp, l[MAXN], r[MAXN];
void dfs(int u){
    l[u] = tsp++;
    for(int i=0; i<g[u].size(); i++)
        dfs(g[u][i]);
    r[u] = tsp;
}

void push_up(node *p){ p->num = lson->num + rson->num; }
void push_down(node *p){
    if(!p->todo) return;
    p->todo = 0;
    lson->num = lson->r - lson->l - lson->num;
    rson->num = rson->r - rson->l - rson->num;
    lson->todo ^= 1;
    rson->todo ^= 1;
}

void build(node *&p, int l, int r){
    p = new node;
    p->l = l;   p->r = r;
    p->num = p->todo = 0;
    if(l+1 == r){
        lson = rson = NULL;
        return;
    }
    int m = (l + r) >> 1;
    build(lson, l, m);
    build(rson, m, r);
}

int query(node *p, int l, int r){
    if(l<=p->l && r>=p->r) return p->num;
    int ret = 0;
    int m = (l + r) >> 1;
    push_down(p);
    if(lson->r > l) ret += query(lson, l, r);
    if(rson->l < r) ret += query(rson, l, r);
    return ret;
}

void update(node *p, int l, int r){
    if(l<=p->l && r>=p->r){
        p->todo ^= 1;
        p->num = p->r - p->l - p->num;
        return;
    }
    int m = (l + r) >> 1;
    push_down(p);
    if(lson->r > l) update(lson, l, r);
    if(rson->l < r) update(rson, l, r);
    push_up(p);
}

void mfree(node *p){
    if(lson) mfree(lson);
    if(rson) mfree(rson);
    delete p;
}

int main(){
    while(scanf(" %d %d", &n, &m)==2){
        int i, j;
        for(i=1; i<=n; i++) g[i].clear();
        for(i=2; i<=n; i++){
            scanf(" %d", &j);
            g[j].push_back(i);
        }
        tsp=1;
        dfs(1);
        build(root, 1, 1+n);
        while(m--){
            char t;
            scanf(" %c %d", &t, &i);
            if(t == 'q') printf("%d
", query(root, l[i], r[i]));
            else update(root, l[i], r[i]);
        }
        mfree(root);
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ramanujan/p/3390060.html