Submission #1094661

#TimeUsernameProblemLanguageResultExecution timeMemory
1094661steveonalexSegments (IZhO18_segments)C++17
75 / 100
5008 ms20360 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define MASK(i) (1LL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() #define block_of_code if(true) ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll gcd(ll a, ll b){return __gcd(a, b);} ll lcm(ll a, ll b){return a / gcd(a, b) * b;} ll LASTBIT(ll mask){return (mask) & (-mask);} int pop_cnt(ll mask){return __builtin_popcountll(mask);} int ctz(ull mask){return __builtin_ctzll(mask);} int logOf(ull mask){return 63 - __builtin_clzll(mask);} mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);} double rngesus_d(double l, double r){ double cur = rngesus(0, MASK(60) - 1); cur /= MASK(60) - 1; return l + cur * (r - l); } template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b) {a = b; return true;} return false; } template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b) {a = b; return true;} return false; } template <class T> void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){ for(auto item: container) out << item << separator; out << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } const int N = 2e5 + 69; const int BLOCK = 2000; int di(int n, int x){ return n / x + (n % x > 0); } struct SQRT{ int n, b_n; vector<vector<int>> a, b_a; SQRT(int _n){ n = _n; b_n = di(n, BLOCK); a.resize(n), b_a.resize(b_n); } void insert(pair<int, int> i){ a[i.first].push_back(i.second); b_a[i.first / BLOCK].push_back(i.second); } void build(){ for(int i= 0; i<n; ++i) sort(ALL(a[i])); for(int i= 0; i<b_n; ++i) sort(ALL(b_a[i])); } int count_larger(vector<int> &a, int x){ int idx = lower_bound(ALL(a), x) - a.begin(); return a.size() - idx; } int get(int l, int r, int x){ // count all pair (i, j) that l <= i <= r and j >= x if (l > r) return 0; int b_l = l / BLOCK, b_r = r / BLOCK; int ans = 0; if (b_l == b_r){ for(int i = l; i<= r; ++i) ans += count_larger(a[i], x); } else{ for(int i = l; i < (b_l + 1) * BLOCK; ++i) ans += count_larger(a[i], x); for(int i = b_r * BLOCK; i <= r; ++i) ans += count_larger(a[i], x); for(int i = b_l + 1; i < b_r; ++i) ans += count_larger(b_a[i], x); } return ans; } }; int q, t; pair<int, int> range[N]; bool erased[N]; int id = 0; int last_ans = 0; int main(void){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); clock_t start = clock(); cin >> q >> t; SQRT st1(0), st2(0); vector<int> X1, X2; vector<array<int, 3>> cur_range; for(int it = 0; it < q; ++it){ if (it % BLOCK == 0){ cur_range.clear(); vector<pair<int, int>> sigma; for(int i = 1; i <= id; ++i) if (!erased[i]) sigma.push_back(range[i]); X1.clear(); X2.clear(); for(pair<int, int> i: sigma){ X1.push_back(i.second); X2.push_back(i.first); } remove_dup(X1); remove_dup(X2); st1 = SQRT(X1.size()), st2 = SQRT(X2.size()); for(pair<int, int> i: sigma){ int idx = lower_bound(ALL(X1), i.second) - X1.begin(); st1.insert({idx, i.second - i.first + 1}); idx = lower_bound(ALL(X2), i.first) - X2.begin(); st2.insert({idx, i.second}); } st1.build(); st2.build(); } int type; cin >> type; if (type == 1){ int l, r; cin >> l >> r; l = l ^ (t * last_ans), r = r ^ (t * last_ans); if (l > r) swap(l, r); range[++id] = {l, r}; cur_range.push_back({{l, r, 1}}); } else if (type == 2){ int i; cin >> i; erased[i] = true; cur_range.push_back({{range[i].first, range[i].second, -1}}); } else{ int l, r, k; cin >> l >> r >> k; l = l ^ (t * last_ans), r = r ^ (t * last_ans); if (l > r) swap(l, r); int ans = 0; if (r - l + 1 >= k){ for(auto i: cur_range){ int cur = min(r, i[1]) - max(l, i[0]) + 1; if (cur >= k) ans += i[2]; } if (!X1.empty()){ // count all range (i, j) whose j is from l + k - 1 to r - 1, and size is >= k int idx1 = lower_bound(ALL(X1), l + k - 1) - X1.begin(); int idx2 = upper_bound(ALL(X1), r) - X1.begin() - 1; ans += st1.get(idx1, idx2, k); // count all range (i, j) whose i is from 0 to r - k + 1, and j is >= r idx1 = 0; idx2 = upper_bound(ALL(X2), r - k + 1) - X2.begin() - 1; ans += st2.get(idx1, idx2, r + 1); } } last_ans = ans; cout << ans << "\n"; } } cerr << "Time elapsed: " << clock() - start << "ms!\n"; 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...