Submission #1230450

#TimeUsernameProblemLanguageResultExecution timeMemory
1230450vux2codeSails (IOI07_sails)C++20
0 / 100
61 ms7748 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; struct SegTree { int n; struct Node { ll mn, lazy; }; vector<Node> st; SegTree(int _n): n(_n), st(4*n+4, {0,0}) {} void apply(int p, ll v) { st[p].mn += v; st[p].lazy += v; } void push(int p) { if (st[p].lazy) { apply(p<<1, st[p].lazy); apply(p<<1|1, st[p].lazy); st[p].lazy = 0; } } void pull(int p) { st[p].mn = min(st[p<<1].mn, st[p<<1|1].mn); } // range add v to [L,R] void update(int p, int l, int r, int L, int R, ll v) { if (L > r || R < l) return; if (L <= l && r <= R) { apply(p, v); return; } push(p); int m = (l + r) >> 1; update(p<<1, l, m, L, R, v); update(p<<1|1, m+1, r, L, R, v); pull(p); } void update(int L, int R, ll v) { update(1, 0, n, L, R, v); } // point query at idx ll query(int p, int l, int r, int idx) { if (l == r) return st[p].mn; push(p); int m = (l + r) >> 1; return idx <= m ? query(p<<1, l, m, idx) : query(p<<1|1, m+1, r, idx); } ll query(int idx) { return query(1, 0, n, idx); } // find first position >= x in [l..r] where value < val int first_below(int p, int l, int r, int x, ll val) { if (r < x || st[p].mn >= val) return -1; if (l == r) return l; push(p); int m = (l + r) >> 1; int res = first_below(p<<1, l, m, x, val); if (res != -1) return res; return first_below(p<<1|1, m+1, r, x, val); } int first_below(int x, ll val) { return first_below(1, 0, n, x, val); } }; int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<int> h(n), k(n); for(int i = 0; i < n; i++) cin >> h[i] >> k[i]; // process in increasing height order vector<int> ord(n); iota(ord.begin(), ord.end(), 0); sort(ord.begin(), ord.end(), [&](int a, int b){ return h[a] < h[b]; }); int H = *max_element(h.begin(), h.end()); SegTree st(H); // exactly the same logic as your BIT version: // let val = st.query(last) // find idx1 = first position < val on [0..h[i]] // find idx2 = first position < val+1 on [0..h[i]] // do two range-adds to simulate adding 1 to [idx1..h[i]] but NOT overshooting for(int i: ord) { int last = h[i] - k[i]; ll val = st.query(last); // how many sails already at 'last' int idx1 = st.first_below(0, val+1); // first pos < val+1 => first < (val+1) == ≤ val int idx2 = st.first_below(0, val+2); // first pos < val+2 => first < (val+2) == ≤ val+1 // now do two range adds: // 1) +1 on [idx1 .. h[i]] // 2) -1 on [idx2 .. h[i]] st.update(idx1, h[i], +1); st.update(idx2, h[i], -1); } // collect answer ll res = 0; for(int i = 0; i <= H; i++){ ll c = st.query(i); res += c * (c-1) / 2; } cout << res << "\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...
#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...