#include <bits/stdc++.h>
using namespace std;
// answer is sum of count[i]*(count[i]-1)/2
// order of masts doesn't matter, so process in ascending order
// choose the K smallest counts to add one to
// start => 2(1) => 3(2) => 3(2) => 4(1) => 4(3) => 5(3)
// 00000 => 100000 => 11100 => 22100 => 22110 => 32220 => 33321
// ans = 3+3+3+1=10
// same as the problem i just did but in reverse lol
struct Tag {
int add;
Tag(int _add) : add(_add) {}
Tag() : add(0) {}
void apply(Tag &tag) { add += tag.add; }
};
struct Info {
int m;
Info(int _m) : m(_m) {}
Info() : m(1<<30) {}
void apply(Tag &tag) { m += tag.add; }
Info combine(Info &other) { return {min(m, other.m)}; }
};
struct Tree {
vector<Tag> tag;
vector<Info> info;
Tree(int size) {
tag.resize(size*4);
info.resize(size*4);
}
void build(vector<Info> &base, int x, int xl, int xr) {
if (xl == xr) {
info[x] = base[xl];
} else {
int xm = (xl + xr) / 2;
build(base, x*2, xl, xm);
build(base, x*2+1, xm+1, xr);
info[x] = info[x*2].combine(info[x*2+1]);
}
}
void pushdown(int x) {
info[x].apply(tag[x]);
if (x*2 < tag.size()) tag[x*2].apply(tag[x]);
if (x*2+1 < tag.size()) tag[x*2+1].apply(tag[x]);
tag[x] = {};
}
Info query(int v, int x, int xl, int xr) {
pushdown(x);
if (xl == xr) {
return info[x];
} else {
int xm = (xl + xr) / 2;
if (v <= xm) return query(v, x*2, xl, xm);
else return query(v, x*2+1, xm+1, xr);
}
}
void update(int l, int r, int x, int xl, int xr, Tag delta) {
if (l > r) return;
if (l == xl && r == xr) {
tag[x].apply(delta);
} else {
int xm = (xl + xr) / 2;
update(l, min(r, xm), x*2, xl, xm, delta);
update(max(l, xm+1), r, x*2+1, xm+1, xr, delta);
pushdown(x); pushdown(x*2); pushdown(x*2+1);
info[x] = info[x*2].combine(info[x*2+1]);
}
}
int find_first(int x, int xl, int xr, function<bool(Info)> pred) {
pushdown(x);
if (xl == xr) {
if (pred(info[x])) return xl;
else return -1;
} else {
pushdown(x*2);
int xm = (xl + xr) / 2;
if (pred(info[x*2])) return find_first(x*2, xl, xm, pred);
else return find_first(x*2+1, xm+1, xr, pred);
}
}
};
const int maxh = 100'000;
int main() {
int N;
cin >> N;
vector<pair<int,int>> masts(N);
for (int i=0; i<N; i++) {
int H, K;
cin >> H >> K;
masts[i] = {H, K};
}
sort(masts.begin(), masts.end());
Tree tree(maxh);
vector<Info> base(maxh);
for (int i=0; i<maxh; i++) base[i] = {0};
tree.build(base, 1, 0, maxh-1);
function<int(int,int)> first_lte = [&](int v, int end) -> int {
int idx = tree.find_first(1, 0, maxh-1, [&](Info info) -> bool {
return info.m <= v;
});
if (idx == -1) return end;
else return idx;
};
for (int i=0; i<N; i++) {
int H = masts[i].first, K = masts[i].second;
int r = H-1;
int l = r-K+1;
int v = tree.query(l, 1, 0, maxh-1).m;
int vl = first_lte(v, r+1);
int vr = first_lte(v-1, r+1) - 1;
int vK = vr-l+1;
K -= vK;
if (K > 0) tree.update(r-K+1, r, 1, 0, maxh-1, {+1});
tree.update(vl, vl+vK-1, 1, 0, maxh-1, {+1});
}
vector<int> ct(maxh);
for (int i=0; i<maxh; i++) ct[i] = tree.query(i, 1, 0, maxh-1).m;
long long ans = 0;
for (int i=0; i<maxh; i++) ans += 1LL * ct[i] * (ct[i] - 1) / 2;
cout << ans << "\n";
return 0;
}
Compilation message
sails.cpp: In member function 'void Tree::pushdown(int)':
sails.cpp:47:13: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Tag>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
47 | if (x*2 < tag.size()) tag[x*2].apply(tag[x]);
| ~~~~^~~~~~~~~~~~
sails.cpp:48:15: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Tag>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
48 | if (x*2+1 < tag.size()) tag[x*2+1].apply(tag[x]);
| ~~~~~~^~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
10 ms |
4188 KB |
Output is correct |
2 |
Correct |
10 ms |
4188 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
10 ms |
4188 KB |
Output is correct |
2 |
Correct |
10 ms |
4184 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
4184 KB |
Output is correct |
2 |
Correct |
10 ms |
4188 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
4188 KB |
Output is correct |
2 |
Correct |
16 ms |
4568 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
13 ms |
4240 KB |
Output is correct |
2 |
Correct |
12 ms |
4188 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
25 ms |
4444 KB |
Output is correct |
2 |
Correct |
65 ms |
4808 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
72 ms |
4700 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
119 ms |
5156 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
184 ms |
5724 KB |
Output is correct |
2 |
Correct |
161 ms |
5712 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
209 ms |
5996 KB |
Output is correct |
2 |
Correct |
120 ms |
5608 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
219 ms |
6128 KB |
Output is correct |
2 |
Correct |
185 ms |
6168 KB |
Output is correct |