Emiliatan

620E

Dec 29th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.00 KB | None | 0 0
  1. /* 620E             */
  2. /* 842 ms, 54936 KB */
  3. #pragma warning( disable : 4996 )
  4. #include <cstdio>
  5. #include <cstring>
  6. #include <cstdint>
  7. #include <cmath>
  8. #include <algorithm>
  9. #include <tuple>
  10. #define ios_jazz ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
  11.  
  12. using namespace std;
  13.  
  14. constexpr int Dir4[4][2] = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
  15. constexpr int Dir8[8][2] = { {-1, -1}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 1} };
  16. constexpr double EPS = 1e-9;
  17. const double PI = acos(-1);
  18.  
  19. using int16 = short;
  20. using uint16 = unsigned short;
  21. using uint = unsigned int;
  22. using int64 = long long;
  23. using uint64 = unsigned long long;
  24. using pii = pair<int, int>;
  25.  
  26. /* main code */
  27. #include <vector>
  28.  
  29. constexpr int MAXN = 4e5;
  30.  
  31. int n, m, colors[MAXN + 1];
  32. auto convert = [](int x) -> int64 { return (int64)1 << x; };
  33. auto popcnt = [](int64 x) {
  34.     int ans = 0;
  35.     for (; x; x -= x & (-x)) ++ans;
  36.     return ans;
  37. };
  38.  
  39. vector<int> E[MAXN + 1];
  40. pii dfn[MAXN + 1]{};
  41. int dfncnt = 1, dedfn[MAXN + 1];
  42.  
  43. void dfs(int);
  44.  
  45. /* segment tree */
  46. auto ls = [](int x) { return x << 1; };
  47. auto rs = [](int x) { return x << 1 | 1; };
  48.  
  49. int64 seg[MAXN << 2 | 1], lazy[MAXN << 2 | 1];
  50.  
  51. void build(int, int, int);
  52. int64 ask(int, int, int, int, int);
  53. void updata(int, int, int, int, int, int);
  54. void maintain(int);
  55. /* */
  56.  
  57. int main()
  58. {
  59.     scanf("%d %d", &n, &m);
  60.  
  61.     for (int i = 1; i <= n; ++i)
  62.         scanf("%d", &colors[i]);
  63.  
  64.     for (int i = 0, x, y; i < n - 1; ++i)
  65.     {
  66.         scanf("%d %d", &x, &y);
  67.  
  68.         E[x].emplace_back(y);
  69.         E[y].emplace_back(x);
  70.     }
  71.  
  72.     dfs(1);
  73.     build(1, n, 1);
  74.  
  75.     for(int t, v, c; m--; )
  76.     {
  77.         scanf("%d", &t);
  78.  
  79.         if (t == 1)
  80.         {
  81.             scanf("%d %d", &v, &c);
  82.             updata(dfn[v].first, dfn[v].second - 1, 1, n, 1, c);
  83.         }
  84.         else
  85.         {
  86.             scanf("%d", &c);
  87.             printf("%d\n", popcnt(ask(dfn[c].first, dfn[c].second - 1, 1, n, 1)));
  88.         }
  89.     }
  90.  
  91.     return 0;
  92. }
  93.  
  94. void dfs(int i = 1)
  95. {
  96.     dfn[i].first = dfncnt, dedfn[dfncnt++] = i;
  97.     for (auto nex : E[i])
  98.     {
  99.         if (dfn[nex].first == 0)
  100.             dfs(nex);
  101.     }
  102.     dfn[i].second = dfncnt;
  103. }
  104.  
  105. void build(int l, int r, int id)
  106. {
  107.     lazy[id] = 0;
  108.     if (l == r) seg[id] = convert(colors[dedfn[l]]);
  109.     else
  110.     {
  111.         int mid = (l + r) >> 1;
  112.  
  113.         build(l, mid, ls(id));
  114.         build(mid + 1, r, rs(id));
  115.  
  116.         seg[id] = seg[ls(id)] | seg[rs(id)];
  117.     }
  118. }
  119.  
  120. void updata(int ql, int qr, int l, int r, int id, int v)
  121. {
  122.     if (ql > r || qr < l)
  123.         return;
  124.  
  125.     if (ql <= l && qr >= r)
  126.         seg[id] = lazy[id] = convert(v);
  127.     else
  128.     {
  129.         int mid = (l + r) >> 1;
  130.  
  131.         maintain(id);
  132.  
  133.         updata(ql, qr, l, mid, ls(id), v);
  134.         updata(ql, qr, mid + 1, r, rs(id), v);
  135.  
  136.         seg[id] = seg[ls(id)] | seg[rs(id)];
  137.     }
  138. }
  139.  
  140. int64 ask(int ql, int qr, int l, int r, int id)
  141. {
  142.     if (ql > r || qr < l) return 0;
  143.    
  144.     if (ql <= l && qr >= r) return seg[id];
  145.    
  146.     int mid = (l + r) >> 1;
  147.     maintain(id);
  148.  
  149.     return ask(ql, qr, l, mid, ls(id)) | ask(ql, qr, mid + 1, r, rs(id));
  150. }
  151.  
  152. void maintain(int id)
  153. {
  154.     if (lazy[id])
  155.         seg[ls(id)] = seg[rs(id)] = lazy[ls(id)] = lazy[rs(id)] = lazy[id];
  156.     lazy[id] = 0;
  157. }
Add Comment
Please, Sign In to add comment