zoukankan      html  css  js  c++  java
  • codeforces 877E

    http://codeforces.com/contest/877/problem/E

    题意:给你一棵树,每个结点 0 、 1 标记。有二种操作( 查询某个结点及其子结点 1 的个数、将某个结点及其子结点的标记取反)。

    题解:线段树 

        w[i] 表示 i 结点在线段树上对应的编号, End[i] 表示 i 结点及其子结点在线段树上编号最大的结点编号

        这样 i 结点及其子结点就可以在线段树上用连续的编号 [ w[i], End[i] ] 表示。

      

    int w[MAXN];
    int End[MAXN], END = 0;
    void dfs(int id, int pr)
    {
        w[id] = ++END;
        for(int i = head[id]; ~i; i = edge[i].next)
        {
            int to = edge[i].to;
            if(to == pr) continue;
            dfs(to, id);
        }
        End[id] = END;
    }

    AC代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #define lson id<<1,l,mid
    #define rson id<<1|1,mid+1,r
    using namespace std;
    const int MAXN = 200000+10;
    int n;
    int a[MAXN];
    struct node
    {
        int to, next;
        node(){
        }
        node(int to, int next) : to(to), next(next){
        }
    }edge[2*MAXN];
    int head[MAXN], alledge;
    void init()
    {
        memset(head, 0xff, sizeof(head));
        alledge = 0;
    }
    void addedge(int x, int y)
    {
        edge[alledge] = node(y, head[x]);
        head[x] = alledge++;
        edge[alledge] = node(x, head[y]);
        head[y] = alledge++;
    }
    int w[MAXN];
    int End[MAXN], END = 0;
    void dfs(int id, int pr)
    {
        w[id] = ++END;
        for(int i = head[id]; ~i; i = edge[i].next)
        {
            int to = edge[i].to;
            if(to == pr) continue;
            dfs(to, id);
        }
        End[id] = END;
    }
    struct treenode
    {
        int num;
        int flag;
    }tree[MAXN<<2];
    void build_tree(int id, int l, int r)
    {
        if(l==r)
        {
            tree[id].num = a[l];
            tree[id].flag = 0;
            return ;
        }
        int mid = l+r>>1;
        build_tree(lson);
        build_tree(rson);
        tree[id].num = tree[id<<1].num+tree[id<<1|1].num;
    }
    void update(int id, int l, int r)
    {
        tree[id].num = r-l+1-tree[id].num;
        tree[id].flag = !tree[id].flag;
    }
    void update(int id, int l, int r, int left, int right)
    {
        if(l==left && r==right)
        {
            tree[id].num = r-l+1-tree[id].num;
            tree[id].flag = !tree[id].flag;
            return ;
        }
        int mid = l+r>>1;
        if( tree[id].flag )
        {
            update(lson);
            update(rson);
            tree[id].flag = 0;
        }
        if(right <= mid)
        {
            update(lson, left, right);
        }
        else if(left > mid)
        {
            update(rson, left, right);
        }
        else
        {
            update(lson, left, mid);
            update(rson, mid+1, right);
        }
        tree[id].num = tree[id<<1].num+tree[id<<1|1].num;
    }
    int query(int id, int l, int r, int left, int right)
    {
        if(l==left && r==right)
        {
            return tree[id].num;
        }
        int mid = l+r>>1;
        if( tree[id].flag )
        {
            update(lson);
            update(rson);
            tree[id].flag = 0;
        }
        if(right <= mid)
        {
            return query(lson, left, right);
        }
        else if(left > mid)
        {
            return query(rson, left, right);
        }
        else
        {
            return query(lson, left, mid) + query(rson, mid+1, right);
        }
    }
    int main (void)
    {
        ios::sync_with_stdio(false);
        init();
        cin >> n;
        for(int i = 2; i <= n; ++i)
        {
            int x; cin >> x;
            addedge(x, i);
        }
        dfs(1, -1);
        for(int i = 1; i <= n; ++i)
        {
            int x; cin >> x;
            a[w[i]] = x;
        }
        build_tree(1, 1, n);
        int q; cin >> q;
        while(q--)
        {
            string c; int x; cin >> c >> x;
            if( c == "pow") update(1, 1, n, w[x], End[x]);
            else cout<<query(1, 1, n, w[x], End[x])<<endl;
        }
        return 0;
    }
  • 相关阅读:
    搭建自己的博客(九):使用shell模式批量添加博客文章并增加分页功能
    搭建自己的博客(八):使用fontawesome框架来添加图标以及美化详情页
    linux系列(十):cat命令
    linux系列(九):touch命令
    搭建自己的博客(七):使用bootstrap框架美化导航栏
    linux系列(八):cp命令
    搭建自己的博客(六):添加首页,使用css对界面做美化
    linux系列(七):mv命令
    Re-enable extensions not coming from Chrome Web Store on Chrome v35+ (with enhanced security)
    liblensfun 在 mingw 上编译时遇到的奇怪问题
  • 原文地址:https://www.cnblogs.com/lkcc/p/7726088.html
Copyright © 2011-2022 走看看