CodeForces620E New Year Tree 61 線段樹 狀態壓縮
阿新 • • 發佈:2018-11-08
題意
- 給你一棵樹,支援兩個操作,\(1\)把一個子樹的顏色更改為\(c\),\(2\)是詢問一個子樹內的顏色數,顏色數\(<=60\)
觀察到顏色數不超過\(long\ long\)
可以把顏色壓成一個長整形數
利用\(dfs\)序把樹上操作變成區間操作
用線段樹維護即可
有一個要注意的地方
__builtin_popcount 預設為\(int\)
要呼叫__builtin_popcountll
Codes
#include <bits/stdc++.h> using namespace std; #define For(i, a, b) for (register int i = (a), i##_end = b; i <= i##_end; ++ i) #define FOR(i, a, b) for (register int i = (a), i##_end = b; i >= i##_end; -- i) #define go(x, i) for (register int i = head[x]; i; i = nxt[i]) #define getc getchar_unlocked #define putc putchar_unlocked #define inf (0x3f3f3f3f) #define INF (2e18) #define pb push_back #define mp make_pair #define x first #define y second #define y1 igniubi typedef long long ll; typedef unsigned long long ull; typedef unsigned int uint; typedef long double ldb; typedef double db; typedef pair<int, int> PII; typedef pair<ll, int> PLI; inline void procStatus() { ifstream t("/proc/self/status"); cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()); } const int N = 4e5 + 10; int to[N << 1], nxt[N << 1], head[N], e; int a[N], st[N], ed[N], rel[N], n, q, cnt; void add(int x, int y) { to[++ e] = y; nxt[e] = head[x]; head[x] = e; } void dfs(int x, int dad) { rel[st[x] = ++ cnt] = x; go(x, i) if(to[i] ^ dad) dfs(to[i], x); ed[x] = cnt; } struct Segment_Tree { #define ls (bh << 1) #define rs (ls | 1) #define mid ((l + r) >> 1) #define lson ls, l, mid #define rson rs, mid + 1, r ll S[N << 2], tag[N << 2]; void pushup(int bh) { S[bh] = S[ls] | S[rs]; } void pushdown(int bh) { if (tag[bh]) S[ls] = S[rs] = tag[ls] = tag[rs] = tag[bh], tag[bh] = 0; } void build(int bh, int l, int r) { if (l == r) S[bh] = 1ll << (a[rel[l]] - 1); else build(lson), build(rson), pushup(bh); } void update(int bh, int l, int r, int x, int y, int z) { if (x <= l && r <= y) S[bh] = tag[bh] = 1ll << (z - 1); else { pushdown(bh); if (x <= mid) update(lson, x, y, z); if (y > mid) update(rson, x, y, z); pushup(bh); } } ll query(int bh, int l, int r, int x, int y) { if (x <= l && r <= y) return S[bh]; pushdown(bh); if (x > mid) return query(rson, x, y); if (y <= mid) return query(lson, x, y); return query(lson, x, y) | query(rson, x, y); } }T; int main() { //freopen("CF620E.in", "r", stdin); //freopen("CF620E.out", "w", stdout); int opt, x, y; scanf("%d%d", &n, &q); For(i, 1, n) scanf("%d", &a[i]); For(i, 2, n) { scanf("%d%d", &x, &y); add(x, y), add(y, x); } dfs(1, 0), T.build(1, 1, n); while (q --) { scanf("%d%d", &opt, &x); if (opt == 1) scanf("%d", &y), T.update(1, 1, n, st[x], ed[x], y); else printf("%d\n", __builtin_popcountll(T.query(1, 1, n, st[x], ed[x]))); } return 0; }