1. 程式人生 > >Codeforces 620E New Year Tree

Codeforces 620E New Year Tree

LINK


題目大意

給你一棵樹
讓你支援子樹染色,子樹查詢顏色個數,顏色數<=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;
}