Codeforces 620E New Year Tree
阿新 • • 發佈:2018-11-10
題目大意
給你一棵樹
讓你支援子樹染色,子樹查詢顏色個數,顏色數<=60, 節點數<=4e5
思路
因為顏色數很少,考慮狀態壓縮變成二進位制
然後直接在dfs序上用線段樹維護就可以了
//Author: dream_maker #include<bits/stdc++.h> using namespace std; //---------------------------------------------- //typename typedef long long ll; //convenient for #define fu(a, b, c) for (int a = b; a <= c; ++a) #define fd(a, b, c) for (int a = b; a >= c; --a) #define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a) //inf of different typename const int INF_of_int = 1e9; const ll INF_of_ll = 1e18; //fast read and write template <typename T> void Read(T &x) { bool w = 1;x = 0; char c = getchar(); while (!isdigit(c) && c != '-') c = getchar(); if (c == '-') w = 0, c = getchar(); while (isdigit(c)) { x = (x<<1) + (x<<3) + c -'0'; c = getchar(); } if (!w) x = -x; } template <typename T> void Write(T x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) Write(x / 10); putchar(x % 10 + '0'); } //---------------------------------------------- const int N = 4e5 + 10; ll val[N << 2], tag[N << 2]; #define LD (t << 1) #define RD (t << 1 | 1) void pushup(int t) { val[t] = val[LD] | val[RD]; } void pushnow(int t, ll vl) { val[t] = tag[t] = vl; } void pushdown(int t) { if (tag[t]) { pushnow(LD, tag[t]); pushnow(RD, tag[t]); tag[t] = 0; } } void modify(int t, int l, int r, int ql, int qr, ll vl) { if (ql <= l && r <= qr) { pushnow(t, vl); return; } pushdown(t); int mid = (l + r) >> 1; if (qr <= mid) modify(LD, l, mid, ql, qr, vl); else if (ql > mid) modify(RD, mid + 1, r, ql, qr, vl); else { modify(LD, l, mid, ql, mid, vl); modify(RD, mid + 1, r, mid + 1, qr, vl); } pushup(t); } ll query(int t, int l, int r, int ql, int qr) { if (ql <= l && r <= qr) return val[t]; pushdown(t); int mid = (l + r) >> 1;ll ans; if (qr <= mid) ans = query(LD, l, mid, ql, qr); else if (ql > mid) ans = query(RD, mid + 1, r, ql, qr); else ans = query(LD, l, mid, ql, mid) | query(RD, mid + 1, r, mid + 1, qr); pushup(t); return ans; } struct Edge { int v, nxt; } E[N << 1]; int head[N], tot = 0; int bg[N], ed[N], ind = 0; int n, m, c[N]; void add(int u, int v) { E[++tot] = (Edge) {v, head[u]}; head[u] = tot; } void dfs(int u, int fa) { bg[u] = ++ind; for (int i = head[u]; i; i = E[i].nxt) { int v = E[i].v; if (v == fa) continue; dfs(v, u); } ed[u] = ind; } int bitcnt(ll a) { int res = 0; while (a) { if (a & 1) ++res; a >>= 1; } return res; } int main() { //freopen("input.txt", "r", stdin); Read(n), Read(m); fu(i, 1, n) Read(c[i]); fu(i, 2, n) { int u, v; Read(u), Read(v); add(u, v); add(v, u); } dfs(1, 0); fu(i, 1, n) modify(1, 1, n, bg[i], bg[i], 1ll << c[i]); while (m--) { int op; Read(op); switch(op) { case 1: { int x, col; Read(x), Read(col); modify(1, 1, n, bg[x], ed[x], 1ll << col); break; } case 2: { int x; Read(x); Write(bitcnt(query(1, 1, n, bg[x], ed[x]))); putchar('\n'); break; } } } return 0; }