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;
}
原文地址:https://www.cnblogs.com/Egoist-/p/7747842.html