zoukankan      html  css  js  c++  java
  • Codeforces Round #442 (Div. 2) 877E

    Codeforces Round #442 (Div. 2) 877E - Danil and a Part-time Job 

    emmmm第一次见的东西感觉都好神奇

    这里dfs序可以通过对树的遍历对各个节点进行区间分配,那么在接下来的线段树中,可以转变为对每个节点所对应的子树进行访问

    一开始感觉有些混乱,emmmm,理解上有困难的话……emmm,其实线段树维护的是区间,

    而dfs序只是根据题意对节点(线段树的叶子?不要去管它的父亲或者线段树数组内部的结构)管辖区间的建立,因为题目中要求访问以*为根的子树的情况,在用到线段树时,

    需要提供区间的左右端点,也就是dfs序所建立的L[*],R[*],只需要将主函数中访问线段树时的区间[L,R]换为【L[*],R[*]】就可以了……

    emmmm好像说了一堆废话orz

    #include<iostream>
    #include<stdio.h>
    #include<string>
    #include<vector>
    using namespace std;
    const int N = 2e5 + 5;
    vector<int>g[N];
    int L[N], R[N];
    int cnt=0, n, T;
    struct tree {
        int l, r, add, c[2];
    }t[N << 2];
    void init()
    {
        for (int i = 0; i < N; i++)
            g[i].clear();
        cnt = 0;
    }
    void dfs(int u, int fa)
    {
        L[u] = ++cnt;
        for (auto v : g[u])
        {
            if (v != fa)
                dfs(v, u);
        }
        R[u] = cnt;
    }
    void push_up(int rt)
    {
        for (int i = 0; i < 2; i++)
            t[rt].c[i] = t[rt << 1].c[i] + t[rt << 1 | 1].c[i];
    }
    void push_down(int rt)
    {
        if (t[rt].add)
        {
            swap(t[rt << 1].c[0], t[rt << 1].c[1]);
            swap(t[rt << 1 | 1].c[0], t[rt << 1 | 1].c[1]);
            t[rt << 1].add ^= 1;
            t[rt << 1 | 1].add ^= 1;
            t[rt].add = 0;
        }
    }
    void build(int l, int r, int rt)
    {
        t[rt].l = l; t[rt].r = r;
        t[rt].add = 0;
        if (l == r)
        {
            t[rt].c[0] = 1;
            t[rt].c[1] = 0;
            return;
        }
        int mid = (l + r) >> 1;
        build(l, mid, rt << 1);
        build(mid + 1, r, rt << 1 | 1);
        push_up(rt);
    }
    void update(int l, int r, int rt)
    {
        if (t[rt].l == l&&t[rt].r == r)
        {
            t[rt].add ^= 1;
            swap(t[rt].c[0], t[rt].c[1]);
            return;
        }
        int mid = (t[rt].l + t[rt].r) >> 1;
        push_down(rt);
        if (r <= mid)
            update(l, r, rt << 1);
        else if (l > mid)
            update(l, r, rt << 1 | 1);
        else
            update(l, mid, rt << 1),update(mid+1, r, rt << 1 | 1);
        push_up(rt);
    }
    int query(int l, int r, int rt)
    {
        if (t[rt].r == r&&t[rt].l == l)
            return t[rt].c[1];
        int mid = (t[rt].l + t[rt].r) >> 1;
        push_down(rt);
        if (r <= mid)
            return query(l, r, rt << 1);
        else if (l > mid)
            return query(l, r, rt << 1 | 1);
        else
            return query(l, mid, rt << 1) + query(mid+1,r, rt << 1 | 1);
    }
    int main()
    {
        init();
        cin >> n;
        for (int i = 2; i <= n; i++)
        {
            cin >> T;
            g[T].push_back(i);
        }
        dfs(1, 1);
        build(1, cnt, 1);
        for (int i = 1; i <= n; i++)
        {
            int m;
            cin >> m;
            if (m)
                update(L[i], L[i], 1);
        }
        cin >> T;
        string s;
        for (int i = 0; i < T; i++)
        {
            int m;
            cin >> s >> m;
            if (s[0] == 'g')
                cout << query(L[m], R[m], 1) << endl;
            else update(L[m], R[m], 1);
        }
        return 0;
    }
  • 相关阅读:
    关于Loki中promtail组件收集日志的几点思考
    安装 loki 轻量级日志监控系统
    官方文档采用Docker方式安装
    使用 Loki 搭建个人日志平台
    Elasticsearch:Node 介绍
    解决centos系统突然间网络不通的问题:Global IPv6 forwarding is disabled in configuration, but not currently disabled in kernel
    postgresql 角色权限
    Pycharm好用的插件
    the trustAnchors parameter must be non-empty(转)
    Django:json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
  • 原文地址:https://www.cnblogs.com/Egoist-/p/7747842.html
Copyright © 2011-2022 走看看