Submission #222276

# Submission time Handle Problem Language Result Execution time Memory
222276 2020-04-13T00:53:49 Z anonymous Pyramid Base (IOI08_pyramid_base) C++14
100 / 100
1859 ms 96412 KB
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#define MAXD 1000005
#define MAXP 400005
using namespace std;
struct event {int x, ylo, yhi, c, type;};
int N, M, B, P, O[MAXP][5];
vector <event> Sweep, Sweep2[MAXD];

class Segtree {
    int ST[MAXD * 4][4], Lazy[MAXD * 4]; //range add, query longest sequence of 0s
    bool Z[MAXD * 4]; //is everything all same
    //longest running chain of min element, prefix, suffix, min
public:
    void reset(int l, int r, int cur) {
        ST[cur][0] = ST[cur][1] = ST[cur][2] = r-l+1;
        ST[cur][3] = 0, Z[cur] = 1, Lazy[cur] = 0;
        if (l != r) {
            int mid = (l + r) >> 1;
            reset(l, mid, 2*cur);
            reset(mid+1, r, 2*cur+1);
        }
    }
    void pushup(int cur) {
        if (ST[2*cur][3] == ST[2*cur+1][3]) {
            ST[cur][0] = max(ST[2*cur][0], ST[2*cur+1][0]);
            ST[cur][1] = ST[2*cur][1] + (Z[2*cur] ? ST[2*cur+1][1] : 0);
            ST[cur][2] = ST[2*cur+1][2] + (Z[2*cur+1] ? ST[2*cur][2] : 0);
            ST[cur][0] = max(ST[cur][0], ST[2*cur][2] + ST[2*cur+1][1]);
        } else if (ST[2*cur][3] > ST[2*cur+1][3]) {
            ST[cur][0] = ST[2*cur+1][0];
            ST[cur][1] = 0;
            ST[cur][2] = ST[2*cur+1][2];
        } else {
            ST[cur][0] = ST[2*cur][0];
            ST[cur][1] = ST[2*cur][1];
            ST[cur][2] = 0;
        }
        ST[cur][3] = min(ST[2*cur][3], ST[2*cur+1][3]);
        Z[cur] = Z[2*cur] && Z[2*cur + 1] && (ST[2*cur][3] == ST[2*cur+1][3]);
    }
    void pushdown(int cur, bool b) {
        ST[cur][3] += Lazy[cur];
        if (!b) {
            Lazy[2*cur] += Lazy[cur];
            Lazy[2*cur+1] += Lazy[cur];
        }
        Lazy[cur] = 0;
    }
    void upd(int val, int lo, int hi, int l, int r, int cur) {
        pushdown(cur, l == r);
        if (hi < l || lo > r) {return;}
        if (lo <= l && hi >= r) {
            Lazy[cur] += val;
            pushdown(cur, l == r);
            return;
        } else {
            int mid = (l + r) >> 1;
            upd(val, lo, hi, l, mid, 2*cur);
            upd(val, lo, hi, mid+1, r, 2*cur+1);
            pushup(cur);
        }
    }
    int Min(int x) {
        pushdown(1,M -x + 1 == 1);
        return(ST[1][3]);
    }
    int Run(int x) {
        pushdown(1,M -x + 1 == 1);
        return(ST[1][0]);
    }
} ST;

bool can(int x) {
    ST.reset(1, M - x + 1, 1);
    Sweep.clear();
    for (int i=0; i<P; i++) {
        Sweep.push_back({O[i][0] - x + 1, O[i][1] - x + 1, O[i][3], O[i][4], 1}); //add
        Sweep.push_back({O[i][2]+1, O[i][1] - x +1, O[i][3], O[i][4], 0}); //remove
        if (O[i][0] > 1) {Sweep.push_back({O[i][0]-1, O[i][1] - x +1, O[i][3], O[i][4], -1});} //query
    }
    Sweep.push_back({1, 0, 0, 0, -1});
    Sweep.push_back({N-x+1, 0, 0, 0, -1});
    sort(Sweep.begin(), Sweep.end(), [](event a, event b) {return(a.x < b.x || (a.x == b.x && a.type > b.type));});
    for (auto e: Sweep) {
        if (e.type == 1) {
            ST.upd(e.c, e.ylo, e.yhi, 1, M - x + 1, 1);
        } else if (e.type == 0) {
            ST.upd(-e.c, e.ylo, e.yhi, 1, M - x + 1, 1);
            if (ST.Min(x) <= B && e.x + x - 1 <= N) {return(true);}
        } else if (e.type == -1) {
            if (ST.Min(x) <= B && e.x + x - 1 <= N) {return(true);}
        }
    }
    return(false);
}

void Case1() { //B > 0
    int lo = 0, hi = min(N, M) + 1;
    while (lo + 1 != hi) {
        int mid = (lo + hi) >> 1;
        if (can(mid)) {lo = mid;}
        else {hi = mid;}
    }
    printf("%d",lo);
}

void Case2() {
    ST.reset(1, M, 1);
    for (int i=0; i<P; i++) {
        Sweep2[O[i][0]].push_back({O[i][0], O[i][1], O[i][3], O[i][4], 1}); //add
        Sweep2[O[i][2]].push_back({O[i][2], O[i][1], O[i][3], O[i][4], 0}); //remove
        assert(O[i][2] >= O[i][0]);
    }
    int pL = 1, pR = 0, Ans = 0;
    while (pL <= N || pR <= N) {
        if (ST.Min(1) == 0 && ST.Run(1) >= pR - pL + 1) {
            Ans = max(Ans, pR-pL+1);
            if (pR == N) {break;}
            pR++;
            for (auto e: Sweep2[pR]) {
                if (e.type) {
                    ST.upd(1, e.ylo, e.yhi, 1, M, 1);
                }
            }
        } else {
            if (pL == N) {break;}
            for (auto e: Sweep2[pL]) {
                if (!e.type) {
                    ST.upd(-1, e.ylo, e.yhi, 1, M, 1);
                }
            }
            pL++;
            if (pR + 1 < pL) {
                pR++;
                for (auto e: Sweep2[pR]) {
                    if (e.type) {
                        ST.upd(1, e.ylo, e.yhi, 1, M, 1);
                    }
                }
            }
        }
    }
    printf("%d", Ans);
}

int main() {
    //freopen("pyin.txt","r",stdin);
    scanf("%d %d\n%d\n%d",&N,&M,&B, &P);
    for (int i=0; i<P; i++) {
        scanf("%d %d %d %d %d",&O[i][0], &O[i][1], &O[i][2], &O[i][3], &O[i][4]); //x1 y1 x2 y2 c
    }
    if (B) {Case1();}
    else {Case2();}
}

Compilation message

pyramid_base.cpp: In function 'int main()':
pyramid_base.cpp:151:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d %d\n%d\n%d",&N,&M,&B, &P);
     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
pyramid_base.cpp:153:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d %d %d %d %d",&O[i][0], &O[i][1], &O[i][2], &O[i][3], &O[i][4]); //x1 y1 x2 y2 c
         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 19 ms 23808 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 19 ms 23808 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 20 ms 23936 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 21 ms 24576 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 29312 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 62 ms 67064 KB Output is correct
2 Correct 68 ms 67000 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 58 ms 66936 KB Output is correct
2 Correct 58 ms 66936 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 45 ms 24928 KB Output is correct
2 Correct 98 ms 25148 KB Output is correct
3 Correct 92 ms 25148 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 305 ms 30568 KB Output is correct
2 Correct 482 ms 30828 KB Output is correct
3 Correct 433 ms 30828 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 487 ms 47216 KB Output is correct
2 Correct 80 ms 26096 KB Output is correct
3 Correct 324 ms 69104 KB Output is correct
4 Correct 839 ms 69228 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 795 ms 69096 KB Output is correct
2 Correct 1415 ms 69732 KB Output is correct
3 Correct 380 ms 49388 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 688 ms 48624 KB Output is correct
2 Correct 1855 ms 70220 KB Output is correct
3 Correct 1736 ms 70248 KB Output is correct
4 Correct 1859 ms 70240 KB Output is correct
5 Correct 1848 ms 70244 KB Output is correct
6 Correct 293 ms 49644 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 697 ms 82552 KB Output is correct
2 Correct 362 ms 43512 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 950 ms 89960 KB Output is correct
2 Correct 913 ms 88616 KB Output is correct
3 Correct 568 ms 89344 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1129 ms 94080 KB Output is correct
2 Correct 1364 ms 96412 KB Output is correct
3 Correct 1384 ms 96408 KB Output is correct
4 Correct 1240 ms 95608 KB Output is correct
5 Correct 838 ms 94180 KB Output is correct