Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma GCC Optimaze("Ofast")
- #include<bits/stdc++.h>
- #define all(x) begin(x),end(x)
- using namespace std;
- using ll = long long;
- using ld = long double;
- const int N = 200200;
- char mem_[450 * 1024 * 1024];
- size_t _ptr = 0;
- void* operator new(size_t cnt) {
- _ptr += cnt;
- return mem_ + _ptr - cnt;
- }
- void operator delete(void *) {}
- vector<int> g[N];
- int val[N];
- int x[N];
- int y[N];
- void Dfs(int from) {
- x[from] = y[from] = val[from];
- for (int to : g[from]) {
- Dfs(to);
- x[from] = min(x[from], x[to]);
- y[from] = max(y[from], y[to]);
- }
- }
- using ui = int;
- const int MVAL = 800800 + 100;
- struct SegmentTree {
- struct Node {
- Node* left = nullptr;
- Node* right = nullptr;
- int cnt = 0;
- Node() {}
- };
- Node* root = new Node();
- SegmentTree() {}
- void Add(Node* v, ui tl, ui tr, ui index) {
- v->cnt++;
- if (tl + 1 < tr) {
- ui tm = (tl + tr) >> 1;
- if (index < tm) {
- if (v->left == nullptr) {
- v->left = new Node();
- }
- Add(v->left, tl, tm, index);
- } else {
- if (v->right == nullptr) {
- v->right = new Node();
- }
- Add(v->right, tm, tr, index);
- }
- }
- }
- int Get(Node* v, ui tl, ui tr, ui l, ui r) {
- if (!v || tl >= r || tr <= l) return 0;
- if (tl >= l && tr <= r) return v->cnt;
- int tm = (tl + tr) >> 1;
- return Get(v->left, tl, tm, l, r) + Get(v->right, tm, tr, l, r);
- }
- };
- struct SegmentTree2D {
- struct Node2D {
- Node2D* left = nullptr;
- Node2D* right = nullptr;
- SegmentTree* tree = nullptr;
- Node2D() {
- tree = new SegmentTree();
- }
- };
- SegmentTree2D() {
- }
- Node2D* root = new Node2D();
- void Add(Node2D* v, ui tl, ui tr, ui x, ui y) {
- v->tree->Add(v->tree->root, 0, MVAL, y);
- if (tl + 1 < tr) {
- ui tm = (tl + tr) >> 1;
- if (x < tm) {
- if (v->left == nullptr) {
- v->left = new Node2D();
- }
- Add(v->left, tl, tm, x, y);
- } else {
- if (v->right == nullptr) {
- v->right = new Node2D();
- }
- Add(v->right, tm, tr, x, y);
- }
- }
- }
- int Get(Node2D* v, ui tl, ui tr, ui l, ui r, ui y1, ui y2) {
- if (!v || tl >= r || tr <= l) return 0;
- if (tl >= l && tr <= r) return v->tree->Get(v->tree->root, 0, MVAL, y1, y2);
- int tm = (tl + tr) >> 1;
- return Get(v->left, tl, tm, l, r, y1, y2) + Get(v->right, tm, tr, l, r, y1, y2);
- }
- };
- int main() {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- int n;
- cin >> n;
- set<int> st;
- for (int i = 0; i < n; i++) {
- int f, t;
- cin >> f >> t;
- f--, t--;
- cin >> val[i];
- if (f >= 0) g[i].push_back(f);
- if (t >= 0) g[i].push_back(t);
- }
- Dfs(0);
- for (int i = 0; i < n; i++) {
- st.insert(x[i]);
- st.insert(y[i]);
- }
- int q;
- cin >> q;
- vector<pair<int,int>> qu(q);
- for (auto& [l, r] : qu) {
- cin >> l >> r;
- st.insert(l);
- st.insert(r);
- }
- {
- int itr = 0;
- map<int, int> mp;
- for (int val : st) mp[val] = itr++;
- for (int i = 0; i < n; i++) {
- x[i] = mp[x[i]];
- y[i] = mp[y[i]];
- }
- for (auto& [l, r] : qu) {
- l = mp[l];
- r = mp[r];
- }
- }
- SegmentTree2D* tree = new SegmentTree2D();
- for (int i = 0; i < n; i++) {
- tree->Add(tree->root, 0, MVAL, x[i], y[i]);
- }
- for (auto& [l, r] : qu) {
- int inside = tree->Get(tree->root, 0, MVAL, l, MVAL, 0, r + 1);
- int left = tree->Get(tree->root, 0, MVAL, 0, MVAL, 0, l);
- int right = tree->Get(tree->root, 0, MVAL, r + 1, MVAL, 0, MVAL);
- int cnt = n - inside - left - right;
- cout << cnt * 2 + 1 << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement