Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define _CRT_SECURE_NO_WARNINGS
- #include<stdio.h>
- #include<iostream>
- #include<vector>
- #include<cmath>
- #include<algorithm>
- #include<memory.h>
- #include<map>
- #include<set>
- #include<queue>
- #include<list>
- #include<sstream>
- #include<cstring>
- #include<numeric>
- using namespace std;
- const int N = 4e5 + 20;
- vector<int> g[N];
- int a[N];
- long long ans[4 * N];
- bool pushing[4 * N];
- int in[N], out[N];
- int p[N];
- int idx = 0;
- int root = -1;
- bool u[N];
- int bitCount(long long v) {
- int res = 0;
- while (v > 0) {
- if (v % 2 != 0) {
- res++;
- }
- v /= 2;
- }
- return res;
- }
- void push(int v) {
- if (pushing[v]) {
- ans[2 * v] = ans[2 * v + 1] = ans[v];
- pushing[2 * v] = pushing[2 * v + 1] = true;
- pushing[v] = false;
- }
- }
- void build(int v, int tl, int tr) {
- if (tl >= tr) {
- ans[v] = 1LL << a[p[tl]];
- pushing[v] = true;
- }
- else {
- int mid = (tl + tr) >> 1;
- build(v * 2, tl, mid);
- build(v * 2 + 1, mid + 1, tr);
- ans[v] = ans[v * 2] | ans[v * 2 + 1];
- pushing[v] = false;
- }
- }
- long long query(int v, int tl, int tr, int l, int r) {
- if (tr < l || r < tl) {
- return 0;
- }
- if (l <= tl && tr <= r) {
- return ans[v];
- }
- push(v);
- int mid = (tl + tr) >> 1;
- long long res = query(v * 2, tl, mid, l, r);
- res |= query(2 * v + 1, mid + 1, tr, l, r);
- ans[v] = ans[2 * v] | ans[2 * v + 1];
- return res;
- }
- void upd(int v, int tl, int tr, int l, int r, long long c) {
- if (tr < l || r < tl) {
- return;
- }
- if (l <= tl && tr <= r) {
- ans[v] = 1LL << c;
- pushing[v] = true;
- return;
- }
- push(v);
- int mid = (tl + tr) >> 1;
- upd(2 * v, tl, mid, l, r, c);
- upd(2 * v + 1, mid + 1, tr, l, r, c);
- ans[v] = ans[v * 2] | ans[v * 2 + 1];
- }
- void dfs(int v) {
- in[v] = idx;
- p[idx++] = v;
- u[v] = true;
- for (auto to : g[v]) {
- if (!u[to]) {
- dfs(to);
- }
- }
- out[v] = idx - 1;
- }
- void addEdge(int x, int y) {
- g[x].push_back(y);
- g[y].push_back(x);
- }
- int main() {
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
- #endif
- int n, m;
- scanf("%d%d", &n, &m);
- for (int i = 0; i < n; i++) {
- scanf("%d", &a[i]);
- }
- for (int i = 0; i < n - 1; i++) {
- int x, y;
- scanf("%d%d", &x, &y);
- addEdge(x - 1, y - 1);
- }
- root = 0;
- dfs(root);
- build(1, 0, n - 1);
- for (int i = 0; i < m; i++) {
- int t;
- scanf("%d", &t);
- if (t == 1) {
- int v, c;
- scanf("%d%d", &v, &c);
- upd(1, 0, n - 1, in[v - 1], out[v - 1], c);
- }
- else {
- int v;
- scanf("%d", &v);
- printf("%d\n", bitCount(query(1, 0, n - 1, in[v - 1], out[v - 1])));
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement