This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
typedef pair < ll, int > pli;
const int MAX=150020;
struct line {
int l, r, y;
};
int n, k, dFull, xMax;
line data[MAX];
void input(){
scanf("%d", &n);
int i, lastX, lastY;
scanf("%d%d", &lastX, &lastY);
for(i=1; i<n; i++){
int nx, ny;
scanf("%d%d", &nx, &ny);
if(ny == lastY){
data[dFull].l = lastX;
data[dFull].r = nx;
data[dFull].y = ny;
dFull++;
}
lastX = nx;
lastY = ny;
}
xMax = lastX;
scanf("%d", &k);
}
vector < int > to[MAX];
int cnt[MAX], p[MAX], pos[MAX];
ll size[MAX], all;
int l[MAX], r[MAX], y[MAX], stack[MAX], top, renum[MAX], rFull;
void init(){
int i;
top = 0;
for(i=0; i<dFull; i++){
while(top && data[stack[top-1]].y > data[i].y) top--;
if(top && data[stack[top-1]].y == data[i].y){
renum[i] = renum[stack[top-1]];
stack[top-1] = i;
} else {
renum[i] = rFull++;
y[renum[i]] = data[i].y;
p[renum[i]] = -1;
if(top){
l[renum[i]] = data[stack[top-1]].r;
p[renum[i]] = renum[stack[top-1]];
}
stack[top++] = i;
}
}
top = 0;
for(i=dFull-1; i>=0; i--){
while(top && data[stack[top-1]].y > data[i].y) top--;
if(top && data[stack[top-1]].y == data[i].y)
stack[top-1] = i;
else {
if(top){
r[renum[i]] = data[stack[top-1]].l;
if(p[renum[i]] == -1 || y[p[renum[i]]] < y[renum[stack[top-1]]])
p[renum[i]] = renum[stack[top-1]];
} else
r[renum[i]] = xMax;
stack[top++] = i;
}
}
for(i=0; i<rFull; i++){
size[i] = (ll)(r[i]-l[i])*(p[i] == -1 ? y[i] : y[i]-y[p[i]]);
if(p[i] != -1){
cnt[p[i]]++;
pos[i] = to[p[i]].size();
to[p[i]].push_back(i);
}
all += size[i];
}
}
priority_queue < pli > pq;
bool deleted[MAX];
void deflate(int from, int first=-1){
if(deleted[from] || from == -1 || cnt[from] != 1) return;
deflate(p[from], from);
int next = first;
if(next == -1){
int i;
for(i=0; i<to[from].size(); i++){
int t = to[from][i];
if(!deleted[t]){
next = t;
break;
}
}
}
p[next] = p[from];
pos[next] = pos[from];
size[next] += size[from];
if(p[from] != -1)
to[p[from]][pos[from]] = next;
deleted[from] = 1;
if(to[next].size() == 0)
pq.push(pli(-size[next], next));
if(first == -1) return deflate(next);
}
void solve(){
int i, leafCnt=0;
for(i=0; i<rFull; i++)
if(to[i].size() == 0){
leafCnt++;
if(p[i] != -1) deflate(p[i]);
pq.push(pli(-size[i], i));
}
if(leafCnt <= k){
printf("%lld\n", all);
return;
} else k = leafCnt-k;
while(k){
pli now = pq.top();
pq.pop();
if(!deleted[now.second] && -now.first == size[now.second]){
k--;
deleted[now.second] = 1;
all += now.first;
if(p[now.second] != -1){
cnt[p[now.second]]--;
deflate(p[now.second]);
}
}
}
printf("%lld\n", all);
}
int main(){
input();
init();
solve();
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |