/** * Segment tree that keeps the elements in sorted order - O(n log n) build time * Finds the number of elements in an interval * that have values between some specified integers a, b in O(log n log n) */ #include #define endl '\n' #define fileIn(a) freopen(a, "r", stdin) #define fileOut(a) freopen(a, "w", stdout) using namespace std; int n; int b[30000000]; map last; struct Node { /// we will keep all elements form the interval /// in sorted order (we can do binary search in the nodes) vector val; int from, to; Node* left; Node* right; } *root; void build(Node* node, int from, int to) { /// like merege sort but we keep the sorted /// subarrays in the nodes of the segment tree node->from = from; node->to = to; if (from == to) { node->val.push_back(b[from]); node->left = nullptr; node->right = nullptr; return; } int mid = (from + to) / 2; node->left = new Node; node->right = new Node; build(node->left, from, mid); build(node->right, mid + 1, to); int i = 0, j = 0; while (i < node->left->val.size() && j < node->right->val.size()) { if (node->left->val[i] < node->right->val[j]) { node->val.push_back(node->left->val[i++]); } else { node->val.push_back(node->right->val[j++]); } } for (i; i < node->left->val.size(); i++) { node->val.push_back(node->left->val[i]); } for (j; j < node->right->val.size(); j++) { node->val.push_back(node->right->val[j]); } } int getEls(Node* node, int from, int to, int f, int t) { if (node->from > to || node->to < from) return 0; if (node->from >= from && node->to <= to) { if (node->val[0] > t || node->val[node->val.size() - 1] < f) return 0; /// 2 binary searches to /// determine the length of the /// interval containing all numbers between /// f and t that are in the current node int l = 0, r = node->val.size() - 1; int ansl = 0; while (l <= r) { int mid = (l + r) / 2; if (node->val[mid] >= f) { ansl = mid; r = mid - 1; } else { l = mid + 1; } } l = 0; r = node->val.size() - 1; int ansr = 0; while (l <= r) { int mid = (l + r) / 2; if (node->val[mid] <= t) { ansr = mid; l = mid + 1; } else { r = mid - 1; } } return (ansr - ansl + 1); } return getEls(node->left, from, to, f, t) + getEls(node->right, from, to, f, t); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int q; cin >> n >> q; for (int i = 0; i < n; i++) { cin >> b[i]; } root = new Node; build(root, 0, n - 1); /// some queries to test the tree for (int i = 0; i < q; i++) { int l, r, f, t; cin >> l >> r >> f >> t; cout << getEls(root, l - 1, r - 1, f, t) << endl; } return 0; }