Submission #1355487

#TimeUsernameProblemLanguageResultExecution timeMemory
1355487vjudge1Sails (IOI07_sails)C++20
100 / 100
314 ms4272 KiB
#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define is insert
#define MSK(k) (1ULL << k)
#define ton(k, vt) (k|((1ULL) << vt))
#define bat(k, vt) ((k >> vt) & 1)
#define elif else if
#define PROBLEM ""
using namespace std;

/*
 /\_/\
(= ._.) ?
/ >0 \>1
*/
// #define and code:

const int maxN = 1e5;
int n, m;
struct node{
    int h, k;
    bool operator < (const node &o) const {
        if(h == o.h){
            return k < o.k;
        }
        return h < o.h;
    }
};
node store[maxN + 7];
struct tree{
    int mi, idx;
};
tree seg[maxN * 4 + 7];
int lz[maxN * 4 + 7];

void push(int id){
    if(!lz[id]){
        return;
    }
    seg[id * 2].mi += lz[id];
    seg[id * 2 + 1].mi += lz[id];
    lz[id * 2] += lz[id];
    lz[id * 2 + 1] += lz[id];

    lz[id] = 0;
}

tree Merge(const tree &s1, const tree &s2){
    tree tmp = {min(s1.mi, s2.mi)};
    if(s1.mi <= s2.mi){
        tmp.idx = s1.idx;
    }
    else{
        tmp.idx = s2.idx;
    }
    return tmp;
}

void update(int id, int l, int r, int u, int v){
    if(l > v || r < u){
        return;
    }
    if(l >= u && r <= v){
        seg[id].mi += 1;
        lz[id] += 1;
        return;
    }
    push(id);
    int mid = (l + r) >> 1;
    update(id * 2, l, mid, u, v);
    update(id * 2 + 1, mid + 1, r, u, v);
    seg[id] = Merge(seg[id * 2], seg[id * 2 + 1]);
}

tree get(int id, int l, int r, int u, int v){
    if(l > v || r < u){
        return {INT_MAX, 0};
    }
    if(l >= u && r <= v){
        return seg[id];
    }
    push(id);
    int mid = (l + r) >> 1;
    tree tmp = Merge(get(id * 2, l, mid, u, v), get(id * 2 + 1, mid + 1, r, u, v));
    seg[id] = Merge(seg[id * 2], seg[id * 2 + 1]);
    return tmp;
}

void build(int id, int l, int r){
    if(l == r){
        seg[id] = {0, l};
        return;
    }
    int mid = (l + r) >> 1;
    build(id * 2, l, mid);
    build(id * 2 + 1, mid + 1, r);
    seg[id] = Merge(seg[id * 2], seg[id * 2 + 1]);
}

void solve(int h, int k){
    int it1 = get(1, 1, m, h - k + 1, h - k + 1).mi;
    int it2 = get(1, 1, m, h - k, h - k).mi;
    if(it1 == it2){
        int lo = h - k + 1;
        int hi = h;
        int tmp = h + 1;
        while(lo <= hi){
            int mid = (lo + hi) >> 1;
            tree val = get(1, 1, m, mid, mid);
            if(val.mi != it1){
                tmp = mid;
                hi = mid - 1;
            }
            else{
                lo = mid + 1;
            }
        }
        // cout << tmp << " --> " << h << '\n';
        update(1, 1, m, tmp, h);
        k -= h - tmp + 1;
        h -= h - tmp + 1;
    }
    elif(it1 != it2){
        update(1, 1, m, h - k + 1, h);
        h -= k;
        k -= k;
    }
    int tmp = get(1, 1, m, 1, h).idx;
    // cout << tmp << " -> " << tmp + k - 1 << '\n';
    update(1, 1, m, tmp, tmp + k - 1);
    // cout << '\n';
}

int main() {
    // freopen(PROBLEM".inp", "r", stdin);
    // freopen(PROBLEM".out", "w", stdout);
    // ios_base::sync_with_stdio(false);
    // cin.tie(NULL);
    // cout.tie(NULL);

    cin >> n;
    for(int i = 1; i <= n; i++){
        int h, k;
        cin >> h >> k;
        store[i] = {h, k};
    }

    sort(store + 1, store + n + 1);
    m = store[n].h;
    build(1, 1, m);

    for(int i = 1; i <= n; i++){
        int h = store[i].h;
        int k = store[i].k;
        int cnt = 0;
        // cout << "!!! " << h << " " << k << '\n';

        solve(h, k);

        // while(k){
        //     tree ans = get(1, 1, m, 1, h);
        //     int val = ans.idx;
        //     // cout << ans.mi << " " << ans.idx << '\n';
        //     // cout << val << '\n';
        //     int tmp = min(h - val + 1, k);
        //     if(tmp + val - 1 == h){
        //         cnt += tmp;
        //     }
        //     else{  
        //         update(1, 1, m, val, val + tmp - 1);
        //     }
        //     // cout << val << " -> " << val + tmp - 1 << '\n';
        //     k -= tmp;
        //     h -= tmp;
        // }
        // update(1, 1, m, store[i].h - cnt + 1, store[i].h);
        // for(int i = 1; i <= m; i++){
        //     ll val = get(1, 1, m, i, i).mi;
        //     cout << val << " ";
        //     // res += val * (val - 1) / 2;
        // }
        // cout << '\n';
    }

    ll res = 0;
    for(int i = 1; i <= m; i++){
        ll val;
        val = get(1, 1, m, i, i).mi;
        // cout << val << " ";
        res += val * (val - 1) / 2;
    }

    cout << res;

    return 00;
}
#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...
#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...