Submission #1094807

#TimeUsernameProblemLanguageResultExecution timeMemory
1094807steveonalexSegments (IZhO18_segments)C++17
75 / 100
5060 ms32208 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 FenwickTree{
    int n;
    vector<vector<int>> a;

    FenwickTree(int _n){
        n = _n;
        a.resize(n + 1);
    }

    void insert(pair<int, int> i){
        i.first++;
        while(i.first <= n){
            a[i.first].push_back(i.second);
            i.first += LASTBIT(i.first);
        }
    }

    void build(){
        for(int i = 1; i<=n; ++i) sort(ALL(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 i, int x){ // count all pair (i, j) that l <= i <= r and j >= x
        i++;
        int ans = 0;
        while(i > 0){
            ans += count_larger(a[i], x);
            i -= LASTBIT(i);
        }   
        return ans;
    }

    int get(int l, int r, int x){
        return get(r, x) - get(l - 1, x);
    }
};

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;

    FenwickTree 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 = FenwickTree(X1.size()), st2 = FenwickTree(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
                    int idx3 = upper_bound(ALL(X2), r - k + 1) - X2.begin() - 1;
                    ans += st2.get(idx3, 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...