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 <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, x1, 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 (stderr)
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: 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]);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |