Submission #50901

#TimeUsernameProblemLanguageResultExecution timeMemory
50901NicksechkoSegments (IZhO18_segments)C++14
75 / 100
5045 ms172032 KiB
#include <iostream> #include <fstream> #include <set> #include <map> #include <string> #include <vector> #include <bitset> #include <algorithm> #include <cstring> #include <cstdlib> #include <cmath> #include <cassert> #include <queue> #define mp make_pair #define pb push_back typedef long long ll; typedef long double ld; #define f first #define s second using namespace std; const int N = 2e5 + 123; int q, n, id, l[N], r[N]; bool used[N]; vector < pair < int, pair < int, int > > > lazy; vector < int > L[4 * N], R[4 * N]; vector < pair < int, int > > segments; void build(int v = 1, int tl = 0, int tr = n - 1) { if (tl > tr) return; if (tl == tr) { L[v].clear(); R[v].clear(); if (tl < segments.size()) { L[v].push_back(segments[tl].first); R[v].push_back(segments[tl].second); } return; } int tm = (tl + tr) / 2; build(v * 2, tl, tm); build(v * 2 + 1, tm + 1, tr); L[v].resize(L[v * 2].size() + L[v * 2 + 1].size()); R[v].resize(R[v * 2].size() + R[v * 2 + 1].size()); merge(L[v * 2].begin(), L[v * 2].end(), L[v * 2 + 1].begin(), L[v * 2 + 1].end(), L[v].begin()); merge(R[v * 2].begin(), R[v * 2].end(), R[v * 2 + 1].begin(), R[v * 2 + 1].end(), R[v].begin()); } int getId(int k) { int ans = -1, l = 0, r = segments.size() - 1; while(l <= r) { int mid = (l + r) / 2; int len = segments[mid].second - segments[mid].first + 1; if (len >= k) { ans = mid; l = mid + 1; } else { r = mid - 1; } } return ans; } int get(int l, int r, int A, int B, int k, int v = 1, int tl = 0, int tr = n - 1) { if (tl > r || tr < l || l > r || tl > tr) return 0; // cout << "l = " << l << " r = " << r << " tl = " << tl << " tr = " << tr << endl; if (l <= tl && tr <= r) { int res = (lower_bound(R[v].begin(), R[v].end(), A + k - 1) - R[v].begin()) + (L[v].end() - upper_bound(L[v].begin(), L[v].end(), B - k + 1)); return res; } int tm = (tl + tr) / 2; // cout << "tm = " << tm << endl; int ans = get(l, r, A, B, k, v * 2, tl, tm) + get(l, r, A, B, k, v * 2 + 1, tm + 1, tr); return ans; } int inter(int l1, int r1, int l2, int r2) { return max(0, min(r1, r2) - max(l1, l2) + 1); } int query(int A, int B, int k) { if (B - A + 1 < k) return 0; int id = getId(k); // cout << "A = " << A << " " << B << " k = " << k << " id = " << id << endl; // for (auto i : segments) cout << i.second - i.first + 1 << " "; // cout << endl; // cout << "start new query\n"; int ans = id + 1 - get(0, id, A, B, k); for (auto i : lazy) { if (inter(i.second.first, i.second.second, A, B) >= k) { if (i.first == 1) ans++; else ans--; } } return ans; } bool cmp(pair < int, int > a, pair < int, int > b) { return a.second - a.first + 1 > b.second - b.first + 1; } void rebuild() { segments.clear(); lazy.clear(); for (int i = 1;i <= id;i++) { if (!used[i]) { segments.pb({l[i], r[i]}); } } sort(segments.begin(), segments.end(), &cmp); n = segments.size(); build(); } int main() { // freopen("input", "r", stdin); // freopen("output", "w", stdout); int G; scanf("%d%d", &q, &G); int K = sqrt(q * 19); int lst_ans = 0; //cout << q << " " << K << endl; for (int i = 0, t, x, was = 0;i < q;i++) { if (i % K == 0) { // cout << "starting\n"; rebuild(); // cout << "Succesfully i = " << i / K << endl; } scanf("%d", &t); if (t == 1) { id++; scanf("%d%d", &l[id], &r[id]); l[id] = l[id] ^ (G * lst_ans); r[id] = r[id] ^ (G * lst_ans); if (l[id] > r[id]) swap(l[id], r[id]); lazy.push_back({1, {l[id], r[id]}}); } if (t == 2) { scanf("%d", &x); used[x] = 1; lazy.push_back({2, {l[x], r[x]}}); } if (t == 3) { int a, b, k; scanf("%d%d%d", &a, &b, &k); a = a ^ (G * lst_ans); b = b ^ (G * lst_ans); if (a > b) swap(a, b); printf("%d\n", lst_ans = query(a, b, k)); } } return 0; }

Compilation message (stderr)

segments.cpp: In function 'void build(int, int, int)':
segments.cpp:43:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if (tl < segments.size()) {
        ~~~^~~~~~~~~~~~~~~~~
segments.cpp: In function 'int main()':
segments.cpp:133:25: warning: unused variable 'was' [-Wunused-variable]
   for (int i = 0, t, x, was = 0;i < q;i++) {
                         ^~~
segments.cpp:129:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d%d", &q, &G);
   ~~~~~^~~~~~~~~~~~~~~~
segments.cpp:139:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &t);
     ~~~~~^~~~~~~~~~
segments.cpp:142:12: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
       scanf("%d%d", &l[id], &r[id]);
       ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
segments.cpp:149:11: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
      scanf("%d", &x);
      ~~~~~^~~~~~~~~~
segments.cpp:155:12: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
       scanf("%d%d%d", &a, &b, &k);
       ~~~~~^~~~~~~~~~~~~~~~~~~~~~
#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...