Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #include <ext/pb_ds/assoc_container.hpp>
- using namespace __gnu_pbds;
- using namespace std;
- #define ff first
- #define ss second
- #define int long long
- #define pb push_back
- #define mp make_pair
- #define pii pair<int,int>
- #define vi vector<int>
- #define mii map<int,int>
- #define pqb priority_queue<int>
- #define pqs priority_queue<int,vi,greater<int> >
- #define setbits(x) __builtin_popcountll(x)
- #define zrobits(x) __builtin_ctzll(x)
- #define mod 1000000007
- #define inf 1e18
- #define ps(x,y) fixed<<setprecision(y)<<x
- #define mk(arr,n,type) type *arr=new type[n];
- #define w(x) int x; cin>>x; while(x--)
- //mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
- typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
- vi c, tin, tout, t, lazy, vis, p2; //p2 is used for storing powers of 2
- vector<vi> g;
- int timr = 0;
- /*void c_p_c()
- {
- ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
- #ifndef ONLINE_JUDGE
- freopen("input.txt", "r", stdin);
- freopen("output.txt", "w", stdout);
- #endif
- }*/
- // In tin vector entry time is stored for all the vector
- // In tout exit time is stoed
- // In vis vector vis[i] denotes the node visited at ith time
- void dfs(int cur, int par)
- {
- tin[cur] = ++timr;
- vis[timr] = cur;
- // for (auto x : g[cur])
- for (int x = 0; x < g[cur].size(); x++)
- {
- if (g[cur][x] != par)
- {
- dfs(g[cur][x], cur);
- }
- }
- tout[cur] = timr;
- }
- int expo(int a, int b)
- {
- int res = 1;
- while (b > 0)
- {
- if (b & 1)
- res = res * a;
- a = a * a;
- b = b >> 1;
- }
- return res;
- }
- void build(int s, int e, int n)
- {
- if (s == e)
- {
- t[n] = p2[c[vis[s]]];
- return;
- }
- int mid = (s + e) / 2;
- build(s, mid, 2 * n);
- build(mid + 1, e, 2 * n + 1);
- t[n] = (t[2 * n] | t[2 * n + 1]);
- }
- void update_range(int s, int e, int l, int r, int n, int val)
- {
- if (lazy[n] != 0)
- {
- t[n] = lazy[n];
- if (s != e)
- {
- lazy[2 * n] = lazy[n];
- lazy[2 * n + 1] = lazy[n];
- }
- lazy[n] = 0;
- }
- if (l > e || s > r)
- return ;
- if (s >= l && r >= e)
- {
- t[n] = p2[val];
- if (s != e)
- {
- lazy[2 * n] = t[n];
- lazy[2 * n + 1] = t[n];
- }
- return ;
- }
- int mid = (s + e) / 2;
- update_range(s, mid, l, r, 2 * n, val);
- update_range(mid + 1, e, l, r, 2 * n + 1, val);
- t[n] = t[2 * n] | t[2 * n + 1];
- }
- void query(int s, int e, int l, int r, int n, int &ans)
- {
- if (lazy[n] != 0)
- {
- t[n] = lazy[n];
- if (s != e)
- {
- lazy[2 * n] = lazy[n];
- lazy[2 * n + 1] = lazy[n];
- }
- lazy[n] = 0;
- }
- if (l > e || s > r)
- return ;
- if (s >= l && r >= e)
- {
- ans = ans | t[n];
- return;
- }
- int mid = (s + e) / 2;
- query(s, mid, l, r, 2 * n, ans);
- query(mid + 1, e, l, r, 2 * n + 1, ans);
- }
- signed main()
- {
- //c_p_c();
- int n, m, i, a, b;
- p2.assign(61, 1);
- for (int i = 1; i <= 60; i++)
- p2[i] = 2 * p2[i - 1];
- cin >> n >> m;
- c.resize(n + 1);
- g.resize(n + 1); tin.resize(n + 10); tout.resize(n + 10); t.assign(4 * n + 10, 0); lazy.assign(4 * n + 10, 0); vis.resize(n + 10);
- for (i = 1; i <= n; i++)
- cin >> c[i];
- for (i = 1; i <= n - 1; i++)
- {
- cin >> a >> b;
- g[a].pb(b);
- g[b].pb(a);
- }
- dfs(1, 0);
- build(1, n, 1);
- // for (i = 1; i <= 2 * n; i++)
- // cout << i << " " << t[i] <<" "<< setbits(t[i])<<endl;
- while (m--)
- {
- int ch;
- cin >> ch;
- if (ch == 1)
- {
- int v, f;
- cin >> v >> f;
- // cout << tin[v] << " " << tout[v] << " #" << endl;
- update_range(1, n, tin[v], tout[v], 1, f);
- // for (i = 1; i <= 2 * n; i++)
- // cout << i << " " << t[i] << endl;
- }
- else
- {
- int v, ans = 0;
- cin >> v;
- query(1, n, tin[v], tout[v], 1, ans);
- cout << setbits(ans) << endl;
- }
- }
- }
Add Comment
Please, Sign In to add comment