Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define _FORTIFY_SOURCE 0
- #pragma GCC optimize("Ofast")
- #pragma GCC optimize("no-stack-protector")
- #pragma GCC optimize("unroll-loops")
- #pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")
- #pragma GCC optimize("fast-math")
- #define left lll
- #define right rrr
- using namespace std;
- const int MAXN = 3e5 + 2007, INF = 2e9 + 2007;
- int n, t, k;
- vector <int> num, tree_min, used(MAXN), left(MAXN), right(MAXN);
- vector <vector <pair <int, int> > > mst(3 * MAXN);
- vector <vector <vector <int> > > seg_tree(3 * MAXN);
- void build2(int v, int tl, int tr) {
- if (tl + 1 == tr) {
- tree_min[v] = num[tl];
- return;
- }
- int tm = (tl + tr) >> 1;
- build2(v * 2, tl, tm);
- build2(v * 2 + 1, tm, tr);
- tree_min[v] = min(tree_min[v * 2], tree_min[v * 2 + 1]);
- }
- int get_min(int v, int tl, int tr, int l, int r) {
- if (tl >= r || l >= tr)
- return INF;
- else if (l <= tl && r >= tr)
- return tree_min[v];
- else {
- int tm = (tl + tr) >> 1;
- return min(get_min(v * 2, tl, tm, l, r), get_min(v * 2 + 1, tm, tr, l, r));
- }
- }
- void upd(int v, int tl, int tr, int pos, int x) {
- if (tl + 1 == tr) {
- tree_min[v] = x;
- return;
- }
- int tm = (tl + tr) >> 1;
- if (pos < tm)
- upd(v * 2, tl, tm, pos, x);
- else
- upd(v * 2 + 1, tm, tr, pos, x);
- tree_min[v] = min(tree_min[v * 2], tree_min[v * 2 + 1]);
- }
- void build3(int pos, int v, int tl, int tr, const vector <int>&kek) {
- if (tl + 1 == tr) {
- seg_tree[pos][v] = {kek[tl]};
- return;
- }
- int tm = (tl + tr) >> 1;
- build3(pos, v * 2, tl, tm, kek);
- build3(pos, v * 2 + 1, tm, tr, kek);
- merge(seg_tree[pos][v * 2].begin(), seg_tree[pos][v * 2].end(), seg_tree[pos][v * 2 + 1].begin(), seg_tree[pos][v * 2 + 1].end(), back_inserter(seg_tree[pos][v]));
- }
- void build(int v, int tl, int tr) {
- if (tl + 1 == tr) {
- mst[v] = {{left[tl], right[tl]}};
- vector <int> kek = {right[tl]};
- seg_tree[v].resize(4);
- build3(v, 1, 0, tr - tl, kek);
- return;
- }
- int tm = (tl + tr) >> 1;
- build(v * 2, tl, tm);
- build(v * 2 + 1, tm, tr);
- merge(mst[v * 2].begin(), mst[v * 2].end(), mst[v * 2 + 1].begin(), mst[v * 2 + 1].end(), back_inserter(mst[v]));
- vector <int> kek;
- for (int i = 0; i < (int)mst[v].size(); i++)
- kek.push_back(mst[v][i].second);
- seg_tree[v].resize(4 * (tr - tl));
- build3(v, 1, 0, tr - tl, kek);
- }
- int get_in_seg_tree(int pos, int v, int tl, int tr, int l, int r, int x) {
- if (tl >= r || l >= tr)
- return 0;
- else if (l <= tl && r >= tr) {
- int res = upper_bound(seg_tree[pos][v].begin(), seg_tree[pos][v].end(), x) - seg_tree[pos][v].begin();
- return (tr - tl) - res;
- }
- else {
- int tm = (tl + tr) >> 1;
- return get_in_seg_tree(pos, v * 2, tl, tm, l, r, x) + get_in_seg_tree(pos, v * 2 + 1, tm, tr, l, r, x);
- }
- }
- int get_ans(int v, int tl, int tr, int l, int r, int l1, int r1) {
- if (l >= tr || tl >= r)
- return 0;
- else if (l <= tl && r >= tr) {
- int lft = -1, rght = tr - tl;
- while (rght - lft > 1) {
- int mid = (rght + lft) >> 1;
- if (mst[v][mid].first < l1)
- lft = mid;
- else
- rght = mid;
- }
- int position = lft;
- int res = get_in_seg_tree(v, 1, 0, tr - tl, 0, lft + 1, r1);
- pair <int, int> need = {r1, -1};
- int nxt = upper_bound(mst[v].begin(), mst[v].end(), need) - mst[v].begin();
- res += (tr - tl - nxt);
- int ll = -1, rr = tr - tl;
- while (rr - ll > 1) {
- int mm = (rr + ll) >> 1;
- if (mst[v][mm].second < l1)
- ll = mm;
- else
- rr = mm;
- }
- res += ll + 1;
- return res;
- }
- else {
- int tm = (tl + tr) >> 1;
- return get_ans(v * 2, tl, tm, l, r, l1, r1) + get_ans(v * 2 + 1, tm, tr, l, r, l1, r1);
- }
- }
- int main() {
- std::ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- cin >> n >> t >> k;
- num.resize(n);
- tree_min.resize(4 * n, INF);
- vector <pair <int, int> > all;
- for (int i = 0; i < n; i++) {
- cin >> num[i];
- all.push_back({num[i], i});
- }
- if (t == 1) {
- int l, r;
- cin >> l >> r;
- l--;
- vector <int> smth;
- for (int i = l; i < r; i++)
- smth.push_back(num[i]);
- sort(smth.begin(), smth.end());
- int ans = 1;
- for (int i = 0; i < (int)smth.size() - 1; i++) {
- if (smth[i + 1] - smth[i] > k)
- ans++;
- }
- cout << ans;
- return 0;
- }
- sort(all.begin(), all.end());
- build2(1, 0, n);
- for (int kek = 0; kek < n; kek++) {
- int i = all[kek].second;
- int l = i, r = n;
- while (r - l > 1) {
- int m = (r + l) >> 1;
- if (get_min(1, 0, n, i + 1, m + 1) <= num[i] + k)
- r = m;
- else
- l = m;
- }
- right[i] = r;
- l = -1;
- r = i;
- while (r - l > 1) {
- int m = (r + l) >> 1;
- if (get_min(1, 0, n, m, i) <= num[i] + k)
- l = m;
- else
- r = m;
- }
- left[i] = l;
- upd(1, 0, n, i, INF);
- }
- tree_min.clear();
- num.clear();
- all.clear();
- build(1, 0, n);
- while (t--) {
- int l, r;
- cin >> l >> r;
- l--;
- cout << get_ans(1, 0, n, l, r, l, r - 1) << " ";
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement