답안 #281649

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
281649 2020-08-23T09:36:44 Z evpipis Pyramid Base (IOI08_pyramid_base) C++11
35 / 100
2495 ms 246180 KB
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
typedef long long ll;

const int len = 1e6+4;
const ll inf = 1e16;
int cost[len], n, m, bud, q;
vector<int> buck[len];

struct rectangle{
    int x1, x2, y1, y2;
} rec[len];

struct{
    struct node{
        ll mn, lazy;

        node(ll mn_ = 0, ll lazy_ = 0){
            mn = mn_;
            lazy = lazy_;
        }
    } tree[4*len];

    void prop(int p, int l, int r){
        if (!tree[p].lazy) return;

        tree[p].mn += tree[p].lazy;
        if (l != r){
            tree[2*p].lazy += tree[p].lazy;
            tree[2*p+1].lazy += tree[p].lazy;
        }
        tree[p].lazy = 0;
    }

    void update(int p, int l, int r, int i, int j, int v){
        prop(p, l, r);

        if (i <= l && r <= j)
            return void(tree[p].lazy += v);

        int mid = (l+r)/2;
        if (i <= mid)
            update(2*p, l, mid, i, j, v);
        if (j >= mid+1)
            update(2*p+1, mid+1, r, i, j, v);

        prop(2*p, l, mid), prop(2*p+1, mid+1, r);
        tree[p].mn = min(tree[2*p].mn, tree[2*p+1].mn);
    }

    ll query(int p, int l, int r, int i, int j){
        prop(p, l, r);

        if (r < i || j < l)
            return inf;
        if (i <= l && r <= j)
            return tree[p].mn;

        int mid = (l+r)/2;
        return min(query(2*p, l, mid, i, j), query(2*p+1, mid+1, r, i, j));
    }
} seg_tree1;

bool check(int k){
    for (int i = 1; i <= q; i++){
        int y1 = rec[i].y1, y2 = rec[i].y2;

        buck[max(1, y1-k+1)].pb(i);
        buck[y2+1].pb(-i);
    }

    bool ans = false;
    for (int y = 1; y <= m+1; y++){
        int must = (y==1);
        for (int j = 0; j < buck[y].size(); j++){
            int i = abs(buck[y][j]);
            int x1 = rec[i].x1, x2 = rec[i].x2;

            if (buck[y][j] > 0)
                seg_tree1.update(1, 1, n, max(1, x1-k+1), x2, cost[i]);
            else
                must = 1, seg_tree1.update(1, 1, n, max(1, x1-k+1), x2, -cost[i]);
        }

        buck[y].clear();
        if (must && y <= m-k+1)
            ans |= (seg_tree1.query(1, 1, n, 1, n-k+1) <= bud);
    }

    return ans;
}

int solve1(){
    int l = 1, r = min(n, m), ans = 0;
    while (l <= r){
        int mid = (l+r)/2;
        if (check(mid))
            ans = mid, l = mid+1;
        else
            r = mid-1;
    }

    return ans;
}

struct{
    struct node{
        int lazy, mn, pref, suf;
        int max_pref, max_suf, max_mn, sz;

        node(int val = 0){
            lazy = 0;
            mn = pref = suf = val;
            sz = max_mn = max_pref = max_suf = 1;
        }

        void join(node &lef, node &rig){
            mn = min(lef.mn, rig.mn);
            max_mn = 0;
            if (lef.mn == mn)
                max_mn = max(max_mn, lef.max_mn);
            if (rig.mn == mn)
                max_mn = max(max_mn, rig.max_mn);
            if (lef.suf == mn && rig.pref == mn)
                max_mn = max(max_mn, lef.max_suf+rig.max_pref);

            sz = lef.sz+rig.sz;

            pref = lef.pref;
            max_pref = lef.max_pref;
            if (lef.max_pref == lef.sz && rig.pref == lef.suf)
                max_pref = lef.sz+rig.max_pref;

            suf = rig.suf;
            max_suf = rig.max_suf;
            if (rig.max_suf == rig.sz && lef.suf == rig.pref)
                max_suf = rig.sz+lef.max_suf;
        }

    } tree[4*len];

    void build(int p, int l, int r){
        if (l == r)
            return void(tree[p] = node());

        int mid = (l+r)/2;
        build(2*p, l, mid);
        build(2*p+1, mid+1, r);

        tree[p].join(tree[2*p], tree[2*p+1]);
    }

    void prop(int p, int l, int r){
        tree[p].mn += tree[p].lazy;
        tree[p].pref += tree[p].lazy;
        tree[p].suf += tree[p].lazy;

        if (l < r){
            tree[2*p].lazy += tree[p].lazy;
            tree[2*p+1].lazy += tree[p].lazy;
        }

        tree[p].lazy = 0;
    }

    void update(int p, int l, int r, int i, int j, int v){
        prop(p, l, r);

        if (r < i || j < l)
            return;
        if (i <= l && r <= j)
            return void(tree[p].lazy += v);

        int mid = (l+r)/2;
        update(2*p, l, mid, i, j, v);
        update(2*p+1, mid+1, r, i, j, v);

        prop(2*p, l, mid), prop(2*p+1, mid+1, r);
        tree[p].join(tree[2*p], tree[2*p+1]);
    }

    /*node query(int p, int l, int r, int i, int j){
        tree[p].prop(p, l, r);

        if (i <= l && r <= j)
            return tree[p];

        int mid = (l+r)/2;
        if (j <= mid)
            return query(2*p, l, mid, i, j);
        if (i >= mid+1)
            return query(2*p+1, mid+1, r, i, j);

        node res;
        res.join(query(2*p, l, mid, i, j), query(2*p+1, mid+1, r, i, j));
        return res;
    }*/

    int max_zero(){
        prop(1, 1, n);
        if (tree[1].mn == 0)
            return tree[1].max_mn;
        return 0;
    }
} seg_tree2;

int solve2(){
    for (int i = 1; i <= q; i++){
        int y1 = rec[i].y1, y2 = rec[i].y2;
        buck[y1].pb(i);
        buck[y2].pb(-i);
    }

    seg_tree2.build(1, 1, n);

    int ans = 0;
    for (int l = 1, r = 0; l <= m; l++){
        while (r <= m && seg_tree2.max_zero() >= r-l+1){
            ans = max(ans, r-l+1);

            r++;
            for (int j = 0; j < buck[r].size(); j++){
                if (buck[r][j] < 0) continue;
                int i = buck[r][j];
                int x1 = rec[i].x1, x2 = rec[i].x2;
                seg_tree2.update(1, 1, n, x1, x2, +1);
            }
        }

        //printf("for l = %d, first invalid r = %d\n", l, r);

        for (int j = 0; j < buck[l].size(); j++){
            if (buck[l][j] > 0) continue;
            int i = -buck[l][j];
            int x1 = rec[i].x1, x2 = rec[i].x2;
            seg_tree2.update(1, 1, n, x2, x2, -1);
        }
    }

    return ans;
}

int main(){
    scanf("%d %d %d %d", &n, &m, &bud, &q);
    for (int i = 1; i <= q; i++)
        scanf("%d %d %d %d %d", &rec[i].x1, &rec[i].y1, &rec[i].x2, &rec[i].y2, &cost[i]);

    if (bud > 0)
        printf("%d\n", solve1());
    else
        printf("%d\n", solve2());
    return 0;
}

Compilation message

pyramid_base.cpp: In function 'bool check(int)':
pyramid_base.cpp:77:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   77 |         for (int j = 0; j < buck[y].size(); j++){
      |                         ~~^~~~~~~~~~~~~~~~
pyramid_base.cpp: In function 'int solve2()':
pyramid_base.cpp:224:31: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  224 |             for (int j = 0; j < buck[r].size(); j++){
      |                             ~~^~~~~~~~~~~~~~~~
pyramid_base.cpp:234:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  234 |         for (int j = 0; j < buck[l].size(); j++){
      |                         ~~^~~~~~~~~~~~~~~~
pyramid_base.cpp:237:17: warning: unused variable 'x1' [-Wunused-variable]
  237 |             int x1 = rec[i].x1, x2 = rec[i].x2;
      |                 ^~
pyramid_base.cpp: In function 'int main()':
pyramid_base.cpp:246:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  246 |     scanf("%d %d %d %d", &n, &m, &bud, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pyramid_base.cpp:248:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  248 |         scanf("%d %d %d %d %d", &rec[i].x1, &rec[i].y1, &rec[i].x2, &rec[i].y2, &cost[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 120 ms 211704 KB Output isn't correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 119 ms 211704 KB Output isn't correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 117 ms 211704 KB Output isn't correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 123 ms 211780 KB Output isn't correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 126 ms 211704 KB Output isn't correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 154 ms 211832 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 173 ms 211704 KB Output is correct
2 Incorrect 157 ms 211704 KB Output isn't correct
# 결과 실행 시간 메모리 Grader output
1 Correct 169 ms 212088 KB Output is correct
2 Correct 197 ms 212216 KB Output is correct
3 Correct 210 ms 212344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 632 ms 214536 KB Output is correct
2 Correct 783 ms 215024 KB Output is correct
3 Correct 654 ms 215084 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1454 ms 217368 KB Output is correct
2 Correct 595 ms 212856 KB Output is correct
3 Correct 275 ms 217068 KB Output is correct
4 Correct 1900 ms 221064 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1922 ms 220208 KB Output is correct
2 Correct 1813 ms 222328 KB Output is correct
3 Correct 1373 ms 215288 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1767 ms 218476 KB Output is correct
2 Correct 2495 ms 225376 KB Output is correct
3 Correct 2445 ms 225360 KB Output is correct
4 Correct 2393 ms 225536 KB Output is correct
5 Correct 2321 ms 225100 KB Output is correct
6 Correct 1455 ms 214944 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 995 ms 231728 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 1342 ms 239904 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1768 ms 241592 KB Output is correct
2 Incorrect 1894 ms 246180 KB Output isn't correct
3 Halted 0 ms 0 KB -