DFS序+線段樹+bitset CF 620E New Year Tree(聖誕樹)

 

題目連接html

題意:node

  一棵以1爲根的樹,樹上每一個節點有顏色標記(<=60),有兩種操做:c++

  1. 能夠把某個節點的子樹的節點(包括自己)都改爲某種顏色ui

  2. 查詢某個節點的子樹上(包括自己)有多少個不一樣的顏色code

思路:htm

  和2012年多校第7場的G題是同類題,DFS序處理出每一個節點管轄的管轄範圍[L[u], R[u]],其中L[u]就是子樹根節點u所在的位置,用線段樹成端更新顏色變化,注意到顏色(<=60),能夠用bitset<60>,0表示沒有這個顏色,1表示有,異或就能區間合併,最後count一下不一樣顏色的個數。blog

另外:get

  之前這種題是作不了的,如今都能秒掉了,說明在進步:)it

#include <bits/stdc++.h>

const int N = 4e5 + 5;
int a[N];
std::vector<int> edge[N];
int L[N], R[N], id[N];
int tim;

#define lson l, mid, o << 1
#define rson mid + 1, r, o << 1 | 1
struct Node {
    std::bitset<60> color;
    int lazy;
};
Node node[N<<2];

void push_up(int o) {
    node[o].color = node[o<<1].color | node[o<<1|1].color;
}

void push_down(int o) {
    if (node[o].lazy != -1) {
        node[o<<1].lazy = node[o<<1|1].lazy = node[o].lazy;
        node[o<<1].color.reset ();
        node[o<<1].color.set (node[o].lazy);
        node[o<<1|1].color.reset ();
        node[o<<1|1].color.set (node[o].lazy);
        node[o].lazy = -1;
    }
}

void build(int l, int r, int o) {
    node[o].lazy = -1;
    node[o].color.reset ();  //clear to 0
    if (l == r) {
        node[o].color.set (a[id[l]]);  //set to 1
        return ;
    }
    int mid = l + r >> 1;
    build (lson);
    build (rson);
    push_up (o);
}

void updata(int ql, int qr, int c, int l, int r, int o) {
    if (ql <= l && r <= qr) {
        node[o].lazy = c;
        node[o].color.reset ();
        node[o].color.set (c);
        return ;
    }
    push_down (o);
    int mid = l + r >> 1;
    if (ql <= mid) {
        updata (ql, qr, c, lson);
    }
    if (qr > mid) {
        updata (ql, qr, c, rson);
    }
    push_up (o);
}

std::bitset<60> query(int ql, int qr, int l, int r, int o) {
    if (ql <= l && r <= qr) {
        return node[o].color;
    }
    push_down (o);
    int mid = l + r >> 1;
    std::bitset<60> ret;
    if (ql <= mid) {
        ret |= query (ql, qr, lson);
    }
    if (qr > mid) {
        ret |= query (ql, qr, rson);
    }
    return ret;
}

void DFS(int u, int fa) {
    L[u] = ++tim; id[tim] = u;
    for (auto v: edge[u]) {
        if (v != fa) {
            DFS (v, u);
        }
    }
    R[u] = tim;
}

int main() {
    int n, m;
    scanf ("%d%d", &n, &m);
    for (int i=1; i<=n; ++i) {
        scanf ("%d", a+i);
        a[i]--;
    }
    for (int i=1; i<n; ++i) {
        int x, y;
        scanf ("%d%d", &x, &y);
        edge[x].push_back (y);
        edge[y].push_back (x);
    }
    tim = 0;
    DFS (1, 0);
    build (1, tim, 1);

    for (int i=0; i<m; ++i) {
        int type, v;
        scanf ("%d%d", &type, &v);
        if (type == 1) {
            int c;
            scanf ("%d", &c);
            c--;
            updata (L[v], R[v], c, 1, tim, 1);
        } else {
            std::bitset<60> ans = query (L[v], R[v], 1, tim, 1);
            printf ("%d\n", ans.count ());
        }
    }
    return 0;
}
相關文章
相關標籤/搜索