題目連接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; }