제출 #683096

#제출 시각아이디문제언어결과실행 시간메모리
683096AlcabelSegments (IZhO18_segments)C++17
100 / 100
2969 ms13928 KiB
#include <bits/stdc++.h> using namespace std; const int maxn = 2e5, perBlock = 448, maxBlocks = (maxn + perBlock - 1) / perBlock; int prefL[maxBlocks + 1][maxBlocks + 1], prefR[maxBlocks + 1][maxBlocks + 1], blocks; int l[maxn], r[maxn], len[maxn], lId[maxn], rId[maxn], lenId[maxn]; char isDel[maxn]; vector<int> toIns, toDel, byLen, byL, byR; bool cmpLen(const int& A, const int& B) { return len[A] < len[B]; } bool cmpL(const int& A, const int& B) { return l[A] < l[B]; } bool cmpR(const int& A, const int& B) { return r[A] < r[B]; } void rebuild() { static vector<int> tmp; tmp.resize(byLen.size() + toIns.size()); // byLen sort(toIns.begin(), toIns.end(), cmpLen); merge(byLen.begin(), byLen.end(), toIns.begin(), toIns.end(), tmp.begin(), cmpLen); byLen.clear(); for (const int& i : tmp) { if (!isDel[i]) { byLen.emplace_back(i); } } // byL sort(toIns.begin(), toIns.end(), cmpL); merge(byL.begin(), byL.end(), toIns.begin(), toIns.end(), tmp.begin(), cmpL); byL.clear(); for (const int& i : tmp) { if (!isDel[i]) { byL.emplace_back(i); } } // byR sort(toIns.begin(), toIns.end(), cmpR); merge(byR.begin(), byR.end(), toIns.begin(), toIns.end(), tmp.begin(), cmpR); byR.clear(); for (const int& i : tmp) { if (!isDel[i]) { byR.emplace_back(i); } } toIns.clear(); toDel.clear(); blocks = ((int)byLen.size() + perBlock - 1) / perBlock; for (int i = 1; i <= blocks; ++i) { for (int j = 1; j <= blocks; ++j) { prefL[i][j] = prefR[i][j] = 0; } } // byLen for (int bId = 0, i = 0; bId < blocks; ++bId) { for (int j = 0; j < perBlock && i < (int)byLen.size(); ++j, ++i) { lenId[byLen[i]] = bId; } } // byL for (int bId = 0, i = 0; bId < blocks; ++bId) { for (int j = 0; j < perBlock && i < (int)byL.size(); ++j, ++i) { lId[byL[i]] = bId; } } // byR for (int bId = 0, i = 0; bId < blocks; ++bId) { for (int j = 0; j < perBlock && i < (int)byR.size(); ++j, ++i) { rId[byR[i]] = bId; } } for (const int& i : byLen) { ++prefL[lenId[i] + 1][lId[i] + 1]; ++prefR[lenId[i] + 1][rId[i] + 1]; } for (int i = 1; i <= blocks; ++i) { for (int j = 1; j <= blocks; ++j) { prefL[i][j] += prefL[i - 1][j] + prefL[i][j - 1] - prefL[i - 1][j - 1]; prefR[i][j] += prefR[i - 1][j] + prefR[i][j - 1] - prefR[i - 1][j - 1]; } } } void solve() { int n, t, lastans = 0; cin >> n >> t; blocks = 0; for (int iter = 0, iterRest = 0, nxtIdx = 0; iter < n; ++iter, ++iterRest) { if (iterRest == perBlock) { rebuild(); iterRest = 0; } int type; cin >> type; if (type == 1) { int a, b; cin >> a >> b; a ^= (t * lastans); b ^= (t * lastans); if (a > b) { swap(a, b); } l[nxtIdx] = a, r[nxtIdx] = b, len[nxtIdx] = b - a + 1; toIns.emplace_back(nxtIdx++); } else if (type == 2) { int i; cin >> i; --i; toDel.emplace_back(i); isDel[i] = true; } else { int a, b, k; cin >> a >> b >> k; a ^= (t * lastans); b ^= (t * lastans); if (a > b) { swap(a, b); } lastans = 0; if (b - a + 1 >= k) { // all that len[i] >= k int bLen = 0, bId = 0, ptrLen = 0, ptr = 0; // ptrLen -> start of the first block where all is good while (bLen < blocks && len[byLen[ptrLen]] < k) { ++bLen; ptrLen += perBlock; } int goodK = 0; goodK += prefL[blocks][blocks] - prefL[bLen][blocks]; for (int i = max(0, ptrLen - perBlock); i < (int)byLen.size() && i < ptrLen; ++i) { if (len[byLen[i]] >= k) { ++goodK; } } // L <= b - k + 1 bId = 0, ptr = 0; // ptr -> start of the first block where smth is bad while (bId < blocks && l[byL[min(ptr + perBlock, (int)byL.size()) - 1]] <= b - k + 1) { ++bId; ptr += perBlock; } int goodKL = 0; goodKL += prefL[blocks][bId] - prefL[bLen][bId]; for (int i = ptr; i < (int)byL.size() && i < ptr + perBlock; ++i) { if (len[byL[i]] >= k && l[byL[i]] <= b - k + 1) { ++goodKL; } } for (int i = max(0, ptrLen - perBlock); i < (int)byLen.size() && i < ptrLen; ++i) { if (len[byLen[i]] >= k && l[byLen[i]] <= b - k + 1) { ++goodKL; if (lId[byLen[i]] == bId) { --goodKL; } } } // R >= a + k - 1 bId = 0, ptr = 0; // ptr -> start of the first block where all is good while (bId < blocks && r[byR[ptr]] < a + k - 1) { ++bId; ptr += perBlock; } int goodKR = 0; goodKR += prefR[blocks][blocks] - prefR[bLen][blocks] - prefR[blocks][bId] + prefR[bLen][bId]; for (int i = max(0, ptr - perBlock); i < (int)byR.size() && i < ptr; ++i) { if (len[byR[i]] >= k && r[byR[i]] >= a + k - 1) { ++goodKR; } } for (int i = max(0, ptrLen - perBlock); i < (int)byLen.size() && i < ptrLen; ++i) { if (len[byLen[i]] >= k && r[byLen[i]] >= a + k - 1) { ++goodKR; if (rId[byLen[i]] == bId - 1) { --goodKR; } } } // cerr << "goodKL: " << goodKL << ", goodKR: " << goodKR << ", goodK: " << goodK << '\n'; lastans = goodKL + goodKR - goodK; // fix with updates for (const int& i : toIns) { if (l[i] <= b - k + 1 && r[i] >= a + k - 1 && len[i] >= k) { ++lastans; } } for (const int& i : toDel) { if (l[i] <= b - k + 1 && r[i] >= a + k - 1 && len[i] >= k) { --lastans; } } } cout << lastans << '\n'; } } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); int T = 1; // cin >> T; while (T--) { solve(); } return 0; }
#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...