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;
    }
    
  • 相关阅读:
    一文总结十大经典排序算法(思维导图 + 动图演示 + 代码实现 C/C++/Python + 致命吐槽)
    VulnHub——Kioptrix Level 2
    史上最全Redis面试题(2020最新版)
    js 根据秒数获取多少小时,多少分钟,多少秒
    RabbitMQ的死信队列
    女朋友也能看懂的多线程同步
    RabbitMQ的备份交换器
    BI Publisher(rtf)模板开发语法大全
    修改CUSTOM.PLL文件调用客户化FORM&修改标准FORM
    EBS客户化迁移SQL
  • 原文地址:https://www.cnblogs.com/ramanujan/p/3390060.html
Copyright © 2011-2022 走看看