zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 校门外的树
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 开心的金明
    Java实现 蓝桥杯VIP 算法训练 开心的金明
    Java实现 蓝桥杯 算法训练 纪念品分组
    Java实现 蓝桥杯 算法训练 纪念品分组
    Java实现 蓝桥杯VIP 算法训练 校门外的树
    Java实现 蓝桥杯VIP 算法训练 统计单词个数
    Java实现 蓝桥杯VIP 算法训练 开心的金明
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3390060.html
Copyright © 2011-2022 走看看