Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <string>
- #include <math.h>
- #include <climits>
- //#pragma GCC optimize("O3, unroll-loops");
- #include <list>
- #include <map>
- #include <set>
- #include <queue>
- #include <unordered_map>
- #include <unordered_set>
- #include <stdexcept>
- //#include <chrono>
- //#include <fstream>
- //#include <bits/stdc++.h>
- #define mp make_pair
- #define pb push_back
- #define eb emplace_back
- #define x first
- #define y second
- #define sz(x) (int)x.size()
- #define all(x) begin(x), end(x)
- #define rall(x) rbegin(x), rend(x)
- #define FOR(i,a,b) for (int i = (a); i < (b); i++)
- #define RFOR(i,b,a) for (int i = (b) - 1; i >= (a); i--)
- using namespace std;
- typedef unsigned long long ull;
- typedef long long ll;
- typedef long double ld;
- typedef pair<int, int> pi;
- typedef pair<ll, ll> pl;
- typedef vector<int> veci;
- typedef vector<bool> vecb;
- typedef vector<vector<int>> vvi;
- typedef vector<vector<bool>> vvb;
- const int INF_I = 1e9;
- const ll INF_LL = 1e18;
- class DSU {
- public:
- DSU(int n) {
- par.assign(n, 0);
- size.assign(n, 1);
- FOR(i, 0, n)
- par[i] = i;
- }
- int find_set(int v);
- void union_sets(int a, int b);
- private:
- int n;
- veci par;
- veci size;
- };
- class node {
- public:
- node() : left(nullptr), right(nullptr), val(0) {};
- ull val;
- node* left;
- node* right;
- };
- class tree {
- public:
- tree(int n) : n(n) {
- vec.assign(n, new node());
- last = new node();
- build(last, 0, n - 1);
- cnt++;
- }
- void update(list<int>& l) {
- for (int i : l) {
- auto last_ = last;
- last = new node();
- upgrade(last_, last, 0, n - 1, i, 1);
- }
- vec[cnt] = last;
- cnt++;
- }
- int get(int l, int r) {
- /*int sum_r = 0;
- for (auto i : vec[r])
- query(i, 0, n - 1, l - 1, r - 1);
- int sum_l = 0;
- for (auto i : vec[l-1])
- query(i, 0, n - 1, l - 1, r - 1);*/
- return query(vec[r], 0, n - 1, l - 1, r - 1) - query(vec[l-1], 0, n - 1, l - 1, r - 1);
- }
- int get(node* v, int l, int r) {
- return query(v, 0, n - 1, l, r);
- }
- node* last;
- vector<node*> vec;
- int n;
- private:
- int cnt = 0;
- void build(node* n, int low, int high)
- {
- if (low == high)
- {
- n->val = 0;
- return;
- }
- int mid = (low + high) >> 1;
- n->left = new node();
- n->right = new node();
- build(n->left, low, mid);
- build(n->right, mid + 1, high);
- n->val = n->left->val + n->right->val;
- }
- void upgrade(node* prev, node* cur, int low, int high, int idx, int value)
- {
- if (idx > high || idx < low || low > high)
- return;
- if (low == high)
- {
- cur->val+=value + (prev == nullptr ? 0 : prev->val);
- return;
- }
- int mid = (low + high) >> 1;
- if (idx <= mid)
- {
- cur->right = prev->right;
- cur->left = new node();
- upgrade(prev->left, cur->left, low, mid, idx, value);
- }
- else
- {
- cur->left = prev->left;
- cur->right = new node();
- upgrade(prev->right, cur->right, mid + 1, high, idx, value);
- }
- cur->val = (cur->left == nullptr ? 0 : cur->left->val) + (cur->right == nullptr ? 0 : cur->right->val);
- }
- void upgrade(node* cur, int low, int high, int idx) {
- if (idx > high || idx < low || low > high || cur == nullptr)
- return;
- if (low == high){
- cur->val++;
- return;
- }
- int mid = (low + high) >> 1;
- if (idx <= mid)
- upgrade(cur->left, low, mid, idx);
- else
- upgrade(cur->right, mid + 1, high, idx);
- cur->val = (cur->left == nullptr ? 0 : cur->left->val) + (cur->right == nullptr ? 0 : cur->right->val);
- }
- int query(node* n, int low, int high, int l, int r)
- {
- if (l > high || r < low || low > high || n == nullptr)
- return 0;
- if (l <= low && high <= r)
- return n->val;
- int mid = (low + high) / 2;
- return query(n->left, low, mid, l, r)
- +
- query(n->right, mid + 1, high, l, r);
- }
- };
- int main() {
- /*ifstream cin("in.txt");
- ofstream cout("out.txt");
- auto start_time = chrono::high_resolution_clock::now();*/
- ios::sync_with_stdio(false);
- cin.tie(0);
- cout.tie(0);
- /*veci t(10, 0);
- CPersistentSegmentTree<int, std::plus<int>> tree(t.begin(), t.end(), 0);
- vector<pi> v = { mp(0, 4), mp(1, 5) };*/
- int n = 1e5;
- int k = 1;
- /*int n, q, k;
- cin >> n >> q >> k;*/
- int q = 6;
- vector<pi> a(n);
- /*a[0].x = 1;
- a[0].y = 0;
- a[n - 1].x = 2;
- a[n - 1].y = n-1;*/
- // for (int i = 1, j = n - 2; i < n/2; i++, j--) {
- // /*cin >> a[i].x;*/
- // a[i].x = a[i-1].x + 2;
- // a[j].x = a[j + 1].x + 2;
- // a[i].y = i;
- // a[j].y = j;
- //}
- for (int i = 0; i < n; i++) {
- /*cin >> a[i].x;*/
- a[i].x = i;
- a[i].y = i;
- }
- sort(all(a), [](pi a1, pi a2) {
- return a1.x < a2.x;
- });
- vector<pi> b(n);
- set<int> out_of;
- int win_l = lower_bound(all(a), mp(a[0].x - k, 0), [](pi a, pi b) {
- return a.x < b.x;
- }) - a.begin();
- int win_r = win_l;
- DSU dsu(n);
- set<int> s;
- for (int i = 0; i < n; i++) {
- int j_l = lower_bound(all(a), mp(a[i].x - k, 0), [](pi a, pi b) {
- return a.x < b.x;
- }) - a.begin();
- int j_r = upper_bound(all(a), mp(a[i].x + k, 0), [](pi a, pi b) {
- return a.x < b.x;
- }) - a.begin() - 1;
- if (i > 0) s.emplace(a[i - 1].y);
- while (win_l < j_l) {
- s.erase(a[win_l].y);
- win_l++;
- }
- while (win_r <= j_r) {
- s.emplace(a[win_r].y);
- win_r++;
- }
- if (s.size() == 0)
- continue;
- auto it = s.lower_bound(a[i].y);
- if (it == s.begin()) {
- b[i] = mp(-1, a[i].y);
- out_of.emplace(i);
- }
- else {
- it--;
- dsu.union_sets(*it, a[i].y);
- b[i] = mp(*it, a[i].y);
- }
- }
- win_l = win_r = lower_bound(all(a), mp(a[*out_of.begin()].x - k, 0), [](pi a, pi b) {
- return a.x < b.x;
- }) - a.begin();
- s.clear();
- for (int i : out_of) {
- int j_l = lower_bound(all(a), mp(a[i].x - k, 0), [](pi a, pi b) {
- return a.x < b.x;
- }) - a.begin();
- int j_r = upper_bound(all(a), mp(a[i].x + k, 0), [](pi a, pi b) {
- return a.x < b.x;
- }) - a.begin() - 1;
- if (i > 0) s.emplace(a[i - 1].y);
- while (win_l < j_l) {
- s.erase(a[win_l].y);
- win_l++;
- }
- while (win_r <= j_r) {
- s.emplace(a[win_r].y);
- win_r++;
- }
- if (s.size() == 0)
- continue;
- auto it = s.upper_bound(a[i].y);
- for ( ; it != s.end(); it++)
- if (dsu.find_set(*it) != dsu.find_set(a[i].y)) {
- b[i] = mp(a[i].y, *it);
- break;
- }
- }
- sort(all(b), [](pi b1, pi b2) {
- return b1.y < b2.y;
- });
- tree t(n + 1);
- win_r = upper_bound(all(b), mp(-1, INT_MAX), [](pi a, pi b) {
- return a.x < b.x;
- }) - b.begin();
- for (int i = 0; i < n && win_r < n; i++) {
- list<int> l;
- while (win_r < n && i == b[win_r].y) {
- l.eb(b[win_r].x);
- win_r++;
- }
- t.update(l);
- }
- while (q--) {
- int l, r;
- cin >> l >> r;
- cout << r - l + 1 - t.get(l, r) << '\n';
- }
- /*auto end_time = chrono::high_resolution_clock::now();
- chrono::duration<double> duration = end_time - start_time;
- cout << duration.count() << "\n";
- cin.close();
- cout.close();*/
- return 0;
- }
- int DSU::find_set(int v)
- {
- return (par[v] == v ? v : par[v] = find_set(par[v]));
- }
- void DSU::union_sets(int a, int b)
- {
- a = find_set(a);
- b = find_set(b);
- if (a != b) {
- if (size[b] > size[a])
- swap(a, b);
- size[a] += size[b];
- par[b] = a;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment