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 <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 (stderr)
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 |
---|
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... |
# | 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... |
# | 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... |