This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 = 500;
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);
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 - 1) - X1.begin() - 1;
ans += st1.get(idx1, idx2, k);
// count all range (i, j) whose i is from 1 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);
}
}
last_ans = ans;
cout << ans << "\n";
}
}
cerr << "Time elapsed: " << clock() - start << "ms!\n";
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |