#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <vector>
using namespace std;
// BEGIN NO SAD
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound
typedef vector<int> vi;
#define f first
#define s second
#define derr if(0) cerr
// END NO SAD
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<vector<ll>> matrix;
const int SZ = 1 << 19;
pair<ll, int> ragetree[2*SZ];
ll ragetreelazy[2*SZ];
void apply(int idx, ll val) {
ragetree[idx].f += val;
if(idx < SZ) ragetreelazy[idx] += val;
}
void pushdown(int idx) {
if(ragetreelazy[idx]) {
apply(2*idx, ragetreelazy[idx]);
apply(2*idx+1, ragetreelazy[idx]);
ragetreelazy[idx] = 0;
}
}
void pullup(int idx) {
ragetree[idx] = max(ragetree[2*idx], ragetree[2*idx+1]);
}
void upd(int idx, int start, int sz, int lhs, int rhs, ll delta) {
int end = start + sz - 1;
if(start > rhs || end < lhs) return;
if(start >= lhs && end <= rhs) apply(idx, delta);
else {
pushdown(idx);
upd(2*idx, start, sz/2, lhs, rhs, delta);
upd(2*idx+1, start+sz/2, sz/2, lhs, rhs, delta);
pullup(idx);
}
}
void upd(int lhs, int rhs, ll delta) {
upd(1, 0, SZ, lhs, rhs, delta);
}
pii vertices[300000];
int n;
ll vertexweight[SZ];
vector<int> treechild[SZ];
int treepar[SZ];
bool consumed[SZ];
int starttov[SZ];
int treestart[SZ];
int treesz[SZ];
int numnodes = 1;
void dfsforeuler(int curr, int& t) {
starttov[t] = curr;
treestart[curr] = t++;
treesz[curr] = 1;
for(int out: treechild[curr]) {
dfsforeuler(out, t);
treesz[curr] += treesz[out];
}
}
void solve() {
for(int i = SZ; i < 2*SZ; i++) ragetree[i].s = i-SZ;
for(int i = SZ-1; i > 0; i--) pullup(i);
cin >> n;
for(int i = 0; i < n; i++) cin >> vertices[i].f >> vertices[i].s;
set<array<int, 4>> sections; // maxx, sz to left, height, id
sections.insert({vertices[n-1].f, vertices[n-1].f, 0, 0});
vector<array<int, 3>> horizontalsegs; // height, lhs, rhs
for(int i = 1; i+1 < n; i += 2) {
horizontalsegs.pb({vertices[i].s, vertices[i].f, vertices[i+1].f});
}
sort(all(horizontalsegs));
for(auto seg: horizontalsegs) {
auto it = sections.lb({seg[1], -1, -1, -1});
assert(it != sections.end());
auto section = *it;
sections.erase(section);
vertexweight[section[3]] = (seg[0] - section[2]) * (section[1]);
derr << "horizontal segment is " << seg[0] << " from " << seg[1] << " to " << seg[2] << endl;
derr << section[3] << ": " << vertexweight[section[3]] << endl;
int sectionlhs = section[0] - section[1];
int sectionrhs = section[0];
if(seg[1] > sectionlhs) {
treechild[section[3]].pb(numnodes);
treepar[numnodes] = section[3];
sections.insert({seg[1], seg[1] - sectionlhs, seg[0], numnodes++});
}
if(seg[2] < sectionrhs) {
treechild[section[3]].pb(numnodes);
treepar[numnodes] = section[3];
sections.insert({sectionrhs, sectionrhs - seg[2], seg[0], numnodes++});
}
}
{
int start = 0;
dfsforeuler(0, start);
}
for(int i = 0; i < numnodes; i++) {
upd(treestart[i], treestart[i] + treesz[i] - 1, vertexweight[i]);
}
int k;
cin >> k;
ll ret = 0;
while(k--) {
auto curr = ragetree[1];
ret += curr.f;
int v = starttov[curr.s];
derr << "drain " << curr.f << " " << curr.s << endl;
while(!consumed[v]) {
derr << "consume " << treestart[v] << " " << treesz[v] << " of weight " << vertexweight[v] << endl;
upd(treestart[v], treestart[v] + treesz[v] - 1, -vertexweight[v]);
consumed[v] = true;
v = treepar[v];
}
}
cout << ret << "\n";
}
// what would chika do
// are there edge cases (N=1?)
// are array sizes proper (scaled by proper constant, for example 2* for koosaga tree)
// integer overflow?
// DS reset properly between test cases
// are you doing geometry in floating points
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
solve();
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
29128 KB |
Output is correct |
2 |
Correct |
18 ms |
29132 KB |
Output is correct |
3 |
Correct |
17 ms |
29156 KB |
Output is correct |
4 |
Correct |
22 ms |
29132 KB |
Output is correct |
5 |
Correct |
24 ms |
29160 KB |
Output is correct |
6 |
Correct |
21 ms |
29172 KB |
Output is correct |
7 |
Correct |
22 ms |
29192 KB |
Output is correct |
8 |
Correct |
21 ms |
29132 KB |
Output is correct |
9 |
Correct |
21 ms |
29156 KB |
Output is correct |
10 |
Correct |
22 ms |
29100 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
28 ms |
29336 KB |
Output is correct |
2 |
Correct |
23 ms |
29260 KB |
Output is correct |
3 |
Correct |
29 ms |
29388 KB |
Output is correct |
4 |
Correct |
23 ms |
29388 KB |
Output is correct |
5 |
Correct |
24 ms |
29316 KB |
Output is correct |
6 |
Correct |
24 ms |
29452 KB |
Output is correct |
7 |
Correct |
24 ms |
29428 KB |
Output is correct |
8 |
Correct |
25 ms |
29388 KB |
Output is correct |
9 |
Correct |
27 ms |
29280 KB |
Output is correct |
10 |
Correct |
25 ms |
29380 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
316 ms |
41788 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
318 ms |
41840 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
373 ms |
41952 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |