답안 #1085886

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1085886 2024-09-09T01:01:26 Z kkzyr Pyramid Base (IOI08_pyramid_base) C++17
70 / 100
5000 ms 65044 KB
#include <iostream>
#include <algorithm>
using namespace std;

const int MAX_N = 1e6 + 1;
const int MAX_OBSTACLES = 4e5 + 1;

int n, m, b;
int num_obstacles;
pair<int, int> obstacle_x[MAX_OBSTACLES];
pair<int, int> obstacle_y[MAX_OBSTACLES];
int cost[MAX_OBSTACLES];

struct event{
    int x, type, y_start, y_end;
};

bool comp(event x, event y){
    return x.x < y.x;
}

event events[2 * MAX_OBSTACLES];

struct node{
    int left_bound, right_bound;
    int min;
    int lazy;
};

node merge(node left, node right){
    return {left.left_bound, right.right_bound, min(left.min + left.lazy, right.min + right.lazy), 0};
}

int size_of_tree;
node tree[4 * MAX_N];

void update(int left, int right, int tree_node, int delta){
    int node_left = tree[tree_node].left_bound;
    int node_right = tree[tree_node].right_bound;
    if (node_right < left or node_left > right){
        return;
    }
    if (node_left >= left and node_right <= right){
        tree[tree_node].lazy += delta;
        return;
    }
    tree[2 * tree_node].lazy += tree[tree_node].lazy;
    tree[2 * tree_node + 1].lazy += tree[tree_node].lazy;
    update(left, right, 2 * tree_node, delta);
    update(left, right, 2 * tree_node + 1, delta);
    tree[tree_node] = merge(tree[2 * tree_node], tree[2 * tree_node + 1]);
}

int ans;

void find_min_cost(int left, int right, int tree_node){
    int node_left = tree[tree_node].left_bound;
    int node_right = tree[tree_node].right_bound;
    if (node_right < left or node_left > right){
        return;
    }
    if (node_left >= left and node_right <= right){
        ans = min(ans, tree[tree_node].min + tree[tree_node].lazy);
        return;
    }
    tree[2 * tree_node].lazy += tree[tree_node].lazy;
    tree[2 * tree_node + 1].lazy += tree[tree_node].lazy;
    find_min_cost(left, right, 2 * tree_node);
    find_min_cost(left, right, 2 * tree_node + 1);
    tree[tree_node] = merge(tree[2 * tree_node], tree[2 * tree_node + 1]);
}

int main(){
    cin >> m >> n >> b >> num_obstacles;
    for (int i = 1;i <= num_obstacles;i++){
        cin >> obstacle_x[i].first >> obstacle_y[i].first >> obstacle_x[i].second >> obstacle_y[i].second >> cost[i];
        events[2 * i - 1] = {obstacle_x[i].first, cost[i], obstacle_y[i].first, obstacle_y[i].second};
        events[2 * i] = {obstacle_x[i].second + 1, -cost[i], obstacle_y[i].first, obstacle_y[i].second};
    }
    sort(events + 1, events + 2 * num_obstacles + 1, comp);
    int lo = 0;
    int hi = n;
    int answer = -1;
    while (lo <= hi){
        int mid = (lo + hi)/2;
        size_of_tree = 1;
        while (size_of_tree < (n - mid + 1)){
            size_of_tree *= 2;
        }
        for (int i = 1;i <= size_of_tree;i++){
            tree[size_of_tree + i - 1] = {i, i, 0, 0};
        }
        for (int i = size_of_tree - 1;i >= 1;i--){
            tree[i] = merge(tree[2 * i], tree[2 * i + 1]);
        }
        int min_overall = 2e9 + 5;
        int ctr = 1;
        int ctr_2 = 1;
        while (ctr <= 2 * num_obstacles and events[ctr].x < mid){
            if (events[ctr].type > 0){
                update(max(1, events[ctr].y_start - mid + 1), min(n - mid + 1, events[ctr].y_end), 1, events[ctr].type);
            }
            ctr++;
        }
        for (int i = 1;i <= m - mid + 1;i++){
            while (ctr_2 <= 2 * num_obstacles and events[ctr_2].x == i){
                if (events[ctr_2].type < 0){
                    update(max(1, events[ctr_2].y_start - mid + 1), min(n - mid + 1, events[ctr_2].y_end), 1, events[ctr_2].type);
                }
                ctr_2++;
            }
            while (ctr <= 2 * num_obstacles and events[ctr].x == (i + mid - 1)){
                if (events[ctr].type > 0){
                    update(max(1, events[ctr].y_start - mid + 1), min(n - mid + 1, events[ctr].y_end), 1, events[ctr].type);
                }
                ctr++;
            }
            ans = 2e9 + 5;
            find_min_cost(1, n - mid + 1, 1);
            min_overall = min(min_overall, ans);
        }
        if (min_overall <= b){
            answer = mid;
            lo = mid + 1;
        }
        else{
            hi = mid - 1;
        }
    }
    cout << answer << '\n';
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 202 ms 4444 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 606 ms 16728 KB Output is correct
2 Correct 2973 ms 33356 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2747 ms 33364 KB Output is correct
2 Correct 920 ms 16728 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 860 KB Output is correct
2 Correct 53 ms 1116 KB Output is correct
3 Correct 49 ms 1324 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 313 ms 5684 KB Output is correct
2 Correct 421 ms 5708 KB Output is correct
3 Correct 404 ms 5460 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1367 ms 18256 KB Output is correct
2 Correct 197 ms 1884 KB Output is correct
3 Correct 327 ms 34508 KB Output is correct
4 Correct 3336 ms 34936 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2063 ms 35208 KB Output is correct
2 Correct 3424 ms 35272 KB Output is correct
3 Correct 1078 ms 19028 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1172 ms 19024 KB Output is correct
2 Correct 3724 ms 35512 KB Output is correct
3 Correct 3697 ms 35668 KB Output is correct
4 Correct 3696 ms 35668 KB Output is correct
5 Correct 3654 ms 35652 KB Output is correct
6 Correct 477 ms 19340 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5066 ms 49428 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5047 ms 57172 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 5065 ms 65044 KB Time limit exceeded
2 Halted 0 ms 0 KB -