Submission #222276

#TimeUsernameProblemLanguageResultExecution timeMemory
222276anonymousPyramid Base (IOI08_pyramid_base)C++14
100 / 100
1859 ms96412 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...