Submission #376158

#TimeUsernameProblemLanguageResultExecution timeMemory
376158ijxjdjdSegments (IZhO18_segments)C++14
100 / 100
4864 ms9932 KiB
#include <bits/stdc++.h>
#define FR(i, N) for (int i = 0; i < int(N); i++)
#define all(x) begin(x), end(x)
#define sz(x) int((x).size())
using namespace std;

using ll = long long;

const int MAXN = (int)(3e5) + 5;
const int K = 600;
const int LIM = 1500;

int curAdd = 0;
int sz = 0;
int e[MAXN][2];
int  mnSz[MAXN];
int mxL[MAXN];
bool del[MAXN];

vector<int> L;
vector<int> Sz;
vector<int> curdel;
void rebuild() {
    auto byL = [&] (const int& lhs, const int& rhs) {
        return e[lhs][0] < e[rhs][0];
    };
    auto byR = [&] (const int& lhs, const int& rhs) {
        return e[lhs][1] < e[rhs][1];
    };
    auto bySz = [&] (const int& lhs, const int& rhs) {
        return (e[lhs][1] - e[lhs][0]) < (e[rhs][1] - e[rhs][0]);
    };
    curdel.clear();
    L.clear();
    Sz.clear();
    curAdd = 0;
    for (int i = 0; i < sz; i++) {
        if (!del[i]) {
            L.push_back(i);
            Sz.push_back(i);
        }
    }

    sort(all(Sz), bySz);
    for (int i = 0; i < Sz.size(); i+=K) {
        mnSz[i] = e[Sz[i]][1] - e[Sz[i]][0] + 1;
        if (i + K >= Sz.size()) {
            sort(Sz.begin()+i, Sz.end(), byL);
        }
        else {
            sort(Sz.begin()+i, Sz.begin()+i+K, byL);
        }
    }

    sort(all(L), byL);
    for (int i = 0; i < L.size(); i+=K) {
        if (i + K >= L.size()) {
            mxL[i] = e[*L.rbegin()][0];
            sort(L.begin()+i, L.end(), byR);
        }
        else {
            mxL[i] = e[*(L.begin()+i+K-1)][0];
            sort(L.begin()+i, L.begin()+i+K, byR);
        }
    }
}
void add(int l, int r) {
    e[sz][0] = l;
    e[sz][1] = r;
    sz++;
    curAdd++;
}
void rem(int i) {
    del[i] = true;
    curdel.push_back(i);
}
bool good(int l, int r, int id, int s) {
    int l2 = max(e[id][0], l);
    int r2 = min(e[id][1], r);
    if (r2 - l2 + 1 >= s) {
        return true;
    }
    return false;
}
int getSz(int l1, int l2, int s) {
    int cnt = 0;
    if (sz(Sz) > 0) {
        for (int j = (sz(Sz)-1)/K * K; j >= 0; j-=K) {
            if (mnSz[j] < s) {
                for (int i = 0; j + i < Sz.size() && i < K; i++) {
                    if (e[Sz[j+i]][1] - e[Sz[j+i]][0] + 1 >= s && l1 <= e[Sz[j+i]][0] && e[Sz[j+i]][0] <= l2) {
                        cnt++;
                    }
                }
                return cnt;
            }
            else {
                int low = j;
                int high = min(sz(Sz)-1, j+K-1);
                if (e[Sz[low]][0] > l2 || e[Sz[high]][0] < l1) {

                }
                else {
                    while (low < high) {
                        int mid = (low + high)/2;
                        if (l1 <= e[Sz[mid]][0]) {
                            high = mid;
                        }
                        else {
                            low = mid+1;
                        }
                    }
                    int bot = high;
                    if (e[Sz[bot]][0] <= l2) {
                        low = j;
                        high = min(sz(Sz)-1, j+K-1);
                        while (low < high) {
                            int mid = (low + high+1)/2;
                            if (e[Sz[mid]][0] <= l2) {
                                low = mid;
                            }
                            else {
                                high = mid-1;
                            }
                        }
                        cnt +=(low - bot + 1);
                    }
                }
            }
        }
    }
    return cnt;
}
int getL(int lb, int rb) {
    int cnt = 0;
    if (sz(L) > 0) {
        for (int j = 0; j < sz(L); j += K) {
            if (mxL[j] >= lb) {
                for (int i = 0; j + i < L.size() && i < K; i++) {
                    if (e[L[j+i]][0] < lb && e[L[j+i]][1] >= rb) {
                        cnt++;
                    }
                }
                return cnt;
            }
            else {
                int low = j;
                int high = min(j+K-1, sz(L)-1);
                if (e[L[high]][1] < rb) {

                }
                else {
                    int h = min(j+K-1, sz(L)-1);
                    while (low < high) {
                        int mid = (low + high)/2;
                        if (e[L[mid]][1] >= rb) {
                            high = mid;
                        }
                        else {
                            low = mid+1;
                        }
                    }
                    cnt += (h - high + 1);
                }
            }
        }
    }
    return cnt;
}

int count(int l, int r, int k) {
    if (r - l + 1 < k) {
        return 0;
    }
    int temp = getSz(l, r-k+1, k) + getL(l, l+k-1);
    for (int ed : curdel) {
        if (good(l, r, ed, k)) {
            temp--;
        }
    }
    for (int i = 1; i <= curAdd; i++) {
        if (good(l, r, sz-i, k)) {
            temp++;
        }
    }
    return temp;
}
int main() {
    L.reserve(MAXN);
    Sz.reserve(MAXN);
    curdel.reserve(K);
	cin.tie(0);
	cin.sync_with_stdio(0);
	int N, t;
	cin >> N >> t;
	int lst = 0;
	FR(iter, N) {
	    if (curdel.size() + curAdd >= LIM) {
            rebuild();
	    }
        int id;
        cin >> id;
        if (id == 1) {
            int l, r;
            cin >> l >> r;
            l = l^(lst*t);
            r = r^(lst*t);
            if (l > r) {
                swap(l, r);
            }
            add(l, r);
        }
        else if (id == 2) {
            int i;
            cin >> i;
            i--;
            rem(i);
        }
        else if (id == 3) {
            int l, r, k;
            cin >> l >> r >> k;
            l = l^(lst*t);
            r = r^(lst*t);
            if (l > r) {
                swap(l, r);
            }
            lst = count(l, r, k);
            cout << lst << '\n';
        }
	}
	return 0;
}

Compilation message (stderr)

segments.cpp: In function 'void rebuild()':
segments.cpp:45:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   45 |     for (int i = 0; i < Sz.size(); i+=K) {
      |                     ~~^~~~~~~~~~~
segments.cpp:47:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   47 |         if (i + K >= Sz.size()) {
      |             ~~~~~~^~~~~~~~~~~~
segments.cpp:56:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   56 |     for (int i = 0; i < L.size(); i+=K) {
      |                     ~~^~~~~~~~~~
segments.cpp:57:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   57 |         if (i + K >= L.size()) {
      |             ~~~~~~^~~~~~~~~~~
segments.cpp: In function 'int getSz(int, int, int)':
segments.cpp:90:39: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   90 |                 for (int i = 0; j + i < Sz.size() && i < K; i++) {
      |                                 ~~~~~~^~~~~~~~~~~
segments.cpp: In function 'int getL(int, int)':
segments.cpp:139:39: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  139 |                 for (int i = 0; j + i < L.size() && i < K; i++) {
      |                                 ~~~~~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...