• 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;
    }
  • 相关阅读:
    Discuz X 2.5 点点(伪静态)
    jq 、xml 省市级联动
    php memcache 初级使用(2)
    关于windows虚拟内存管理的页目录自映射
    SharePoint 2010 网络上的开发经验和资源
    SharePoint 2010 Reporting Services 报表服务器正在内置 NT AUTHORITY\SYSTEM 账户下运行 解决方法
    SharePoint 2010 Reporting Services 报表服务器无法解密用于访问报表服务器数据库中的敏感数据或加密数据的对称密钥 解决方法
    Active Directory Rights Management Services (AD RMS)无法检索证书层次结构。 解决方法
    SharePoint 2010 Reporting Services 报表服务器实例没有正确配置 解决方法
    SharePoint 2010 页面引用 Reporting Services 展现 List 报表
  • 原文地址:https://www.cnblogs.com/lkcc/p/7726088.html
Copyright © 2020-2023  润新知