Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Failure:
- Can't do lazy propagation on MainTree.
- */
- #include <bits/stdc++.h>
- using namespace std;
- typedef pair<int, int> pii;
- const int N = 100100;
- const int Q = 100100;
- int n, q;
- vector<int> graph[N];
- pair<int, int> queries[Q];
- int timer;
- int tin[N], tout[N];
- void dfs(int node, int par) {
- tin[node] = timer++;
- for (int to : graph[node]) {
- if (to == par) continue;
- dfs(to, node);
- }
- tout[node] = timer-1;
- }
- struct ColorManager {
- struct PosHandler {
- vector<int> pos;
- inline void comp_all() {
- sort(pos.begin(), pos.end());
- pos.erase(unique(pos.begin(), pos.end()), pos.end());
- }
- inline int get_comp(int i) {
- return lower_bound(pos.begin(), pos.end(), i) - pos.begin();
- }
- } poshandler[N];
- int cbegin[N];
- int vecsize;
- int vec[2*Q];
- typedef pair<int, bool> Node;
- Node tree[8*Q];
- void build() {
- vecsize = 1;
- vec[0] = 0;
- for (int c = 1; c <= n; ++c) {
- poshandler[c].comp_all();
- cbegin[c] = vecsize;
- vecsize += poshandler[c].pos.size();
- for (int j = cbegin[c], i = 0; j < vecsize; ++j, ++i) {
- vec[j] = poshandler[c].pos[i];
- }
- }
- // for (int i = 0; i < 8*Q; ++i) {
- // tree[i].first = 0;
- // tree[i].second = false;
- // }
- cout<<"CH: vecsize="<<vecsize<<"\n";
- cout<<"CH: i: ";
- for (int i = 1; i < vecsize; ++i) cout << i << " ";
- cout<<"\nCH: c: ";
- for (int c = 1; c <= n; ++c) {
- for (int i = cbegin[c]; i-cbegin[c] < (int)poshandler[c].pos.size(); ++i) {
- cout << c << " ";
- }
- }
- cout << "\nCH: a: ";
- for (int c = 1; c <= n; ++c) {
- for (int i = cbegin[c]; i-cbegin[c] < (int)poshandler[c].pos.size(); ++i) {
- cout << vec[i] << " ";
- }
- }
- cout << "\n";
- }
- inline void update(int c, int l, int r) {
- l = cbegin[c] + poshandler[c].get_comp(l);
- r = cbegin[c] + poshandler[c].get_comp(r);
- cout << " CM: starting update c="<<c<<" l="<<l<<" r="<<r<<"\n";
- update(1, 1, vecsize-1, l, r);
- }
- inline int query(int c, int l, int r) {
- l = cbegin[c] + poshandler[c].get_comp(l);
- r = cbegin[c] + poshandler[c].get_comp(r);
- return query(1, 1, vecsize-1, l, r);
- }
- inline void push(Node &v, Node &l, Node &r, int tl, int tr) {
- if (!v.second) return;
- int tm = (tl + tr) / 2;
- l.first = vec[tm] - vec[tl] + 1;
- l.second = true;
- r.first = vec[tr] - vec[tm+1] + 1;
- r.second = true;
- v.second = false;
- }
- void update(int v, int tl, int tr, int l, int r) {
- if (l > r) return;
- if (l == tl && tr == r) {
- tree[v].first = vec[tr] - vec[tl] + 1;
- cout<<" CM: updated ["<<l<<","<<r<<"], first="<<tree[v].first<<"\n";
- tree[v].second = true;
- return;
- }
- push(tree[v], tree[2*v], tree[2*v+1], tl, tr);
- int tm = (tl + tr) / 2;
- update(2*v, tl, tm, l, min(r, tm));
- update(2*v+1, tm+1, tr, max(l, tm+1), r);
- tree[v].first = tree[2*v].first + tree[2*v+1].first;
- }
- int query(int v, int tl, int tr, int l, int r) {
- if (l > r) return 0;
- if (l <= tl && tr <= r) return tree[v].first;
- push(tree[v], tree[2*v], tree[2*v+1], tl, tr);
- int tm = (tl + tr) /2;
- return query(2*v, tl, tm, l, min(r, tm))
- + query(2*v+1, tm+1, tr, max(l, tm+1), r);
- }
- } cmanager;
- struct MainTree {
- typedef pair<int, int> Node;
- Node tree[4*N];
- void build() {
- // for (int i = 0; i < 4*N; ++i) {
- // tree[i] = 0;
- // }
- }
- inline void update(int c, int l, int r) {
- // cout << "MT: starting update c="<<c<<" l="<<l<<" r="<<r<<"\n";
- return update(1, 1, n, l, r, c);
- }
- inline int query(int l, int r) {
- cout << "MT: starting query l="<<l<<" r="<<r<<"\n";
- return query(1, 1, n, l, r);
- }
- inline void push(Node &v, Node &l, Node &r) {
- }
- void update(int v, int tl, int tr, int l, int r, int c) {
- if (l > r) return;
- if (l == tl && tr == r) {
- int old = cmanager.query(c, l, r);
- tree[v].first += r-l+1 - old;
- /*
- Failure.
- */
- //tree[v].second += r-l+1 - old;
- cout << " MT: updated c="<<c<<" l="<<l<<" r="<<r<<" CMQ="<<old<<" res="<<tree[v]<<"\n";
- cmanager.update(c, l, r);
- return;
- }
- push(tree[v], tree[2*v], tree[2*v+1]);
- int tm = (tl + tr) / 2;
- update(2*v, tl, tm, l, min(r, tm), c);
- update(2*v+1, tm+1, tr, max(l, tm+1), r, c);
- tree[v] = tree[2*v] + tree[2*v+1];
- }
- int query(int v, int tl, int tr, int l, int r) {
- if (l > r) return 0;
- if (l <= tl && tr <= r) return tree[v];
- push(tree[v], tree[2*v], tree[2*v+1]);
- int tm = (tl + tr) / 2;
- return query(2*v, tl, tm, l, min(r, tm))
- + query(2*v+1, tm+1, tr, max(l, tm+1), r);
- }
- } maintree;
- int main() {
- cin.tie(0)->sync_with_stdio(0);
- #ifndef _DEBUG
- freopen("snowcow.in", "r", stdin);
- freopen("snowcow.out", "w", stdout);
- #endif // _DEBUG
- cin >> n >> q;
- for (int i = 0; i < n-1; ++i) {
- int a, b;
- cin >> a >> b;
- graph[a].push_back(b);
- graph[b].push_back(a);
- }
- timer = 1;
- dfs(1, -1);
- for (int node = 1; node <= n; ++node) {
- cout << node << " -> ["<<tin[node]<<", "<<tout[node]<<"]\n";
- }
- for (int i = 0; i < q; ++i) {
- int type;
- cin >> type;
- if (type == 1) {
- int node, c;
- cin >> node >> c;
- cmanager.poshandler[c].pos.push_back(tin[node]);
- cmanager.poshandler[c].pos.push_back(tout[node]);
- queries[i] = make_pair(node, c);
- } else {
- int node;
- cin >> node;
- queries[i] = make_pair(node, 0);
- }
- }
- cmanager.build();
- maintree.build();
- for (int i = 0; i < q; ++i) {
- int node, c;
- tie(node, c) = queries[i];
- if (c != 0) {
- maintree.update(c, tin[node], tout[node]);
- } else {
- int ans = maintree.query(tin[node], tout[node]);
- cout << ans << '\n';
- // return 0;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement