Codeforces Round #442 (Div. 2) 877E - Danil and a Part-time Job dfs序+线段树

Posted #WoNderlAnd#

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #442 (Div. 2) 877E - Danil and a Part-time Job dfs序+线段树相关的知识,希望对你有一定的参考价值。

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

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

#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;
}

 

以上是关于Codeforces Round #442 (Div. 2) 877E - Danil and a Part-time Job dfs序+线段树的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #442 (Div. 2) B. Nikita and string

Codeforces Round #442 (Div. 2) C. Slava and tanks

Codeforces Round #442 (Div. 2) 877E - Danil and a Part-time Job dfs序+线段树

Codeforces Round #436 E. Fire(背包dp+输出路径)

[ACM]Codeforces Round #534 (Div. 2)

Codeforces_442_A