Submission #1345193

#TimeUsernameProblemLanguageResultExecution timeMemory
1345193SmuggingSpunGarden (JOI23_garden)C++20
100 / 100
480 ms137780 KiB
#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
const int INF = 1e9 + 36;
template<class T>void minimize(T& a, T b){
  if(a > b){
    a = b;
  }
}
template<class T>void maximize(T& a, T b){
  if(a < b){
    a = b;
  }
}
const int lim_d = 5e3 + 5;
int n, m, d, ans = INF;
vector<int>xdot, ydot, xline, yline;
namespace sub1{
  void solve(){
    bitset<lim_d>hx, hy;
    hx.reset();
    hy.reset();
    for(int i = 0; i < n; i++){
      hx[xdot[i]] = hy[ydot[i]] = true;
    }
    int init_max_y = *max_element(ydot.begin(), ydot.end());
    for(int i = 0, max_x = *max_element(xdot.begin(), xdot.end()); i < d; i++){
      for(int j = 0, max_y = init_max_y; j < d; j++){
        if((max_x - i + 1) * (max_y - j + 1) < ans){
          vector<pair<int, int>>event;
          for(int k = 0; k < m; k++){
            if(yline[k] >= j){
              if(yline[k] > 0){
                event.push_back(make_pair(yline[k] - 1, k));
              }
            }
            else{
              event.push_back(make_pair(yline[k] + d - 1, k));
            }
          }
          sort(event.begin(), event.end(), greater<pair<int, int>>());
          int cur_max_x = max_x;
          for(int k = 0; k < event.size(); k++){
            if(k == 0 || event[k - 1].first != event[k].first){
              minimize(ans, (cur_max_x - i + 1) * (max(event[k].first + 1, max_y) - j + 1));
            }
            maximize(cur_max_x, xline[event[k].second] + (xline[event[k].second] < i ? d : 0));
          }
          minimize(ans, (cur_max_x - i + 1) * (max_y - j + 1));
        }
        if(hy[j]){
          max_y = j + d;
        }
      }
      if(hx[i]){
        max_x = i + d;
      }
    }
    cout << ans;
  }
}
namespace sub234{
  void solve(){
    for(int i = 0; i < d; i++){
      for(int j = 0; j < d; j++){
        int max_x = 0, max_y = 0;
        for(int k = 0; k < n; k++){
          maximize(max_x, xdot[k] + (xdot[k] < i ? d : 0));
          maximize(max_y, ydot[k] + (ydot[k] < j ? d : 0));
        }
        vector<vector<int>>event(d << 1);
        for(int k = 0; k < m; k++){
          if(yline[k] >= j){
            if(yline[k] > 0){
              event[yline[k] - 1].push_back(k);
            }
          }
          else{
            event[yline[k] + d - 1].push_back(k);
          }
        }
        for(int k = (d << 1) - 1; k >= max_y; k--){
          for(int& t : event[k]){
            maximize(max_x, xline[t] + (xline[t] < i ? d : 0));
          }
          minimize(ans, (max_x - i + 1) * (k - j + 1));
        }
      }
    }
    cout << ans;
  }
}
namespace sub5{
  void solve(){
    vector<int>nxt(d + 1), pre(d + 1), cnt(d);
    vector<vector<int>>event(d << 1);
    int max_gap;
    function<void(int)>remove = [&] (int x){
      nxt[pre[x]] = nxt[x];
      pre[nxt[x]] = pre[x];
      if(nxt[x] != d && pre[x] != d){
        maximize(max_gap, nxt[x] - pre[x]);
      }
    };
    for(int lx = 0; lx < d; lx++){
      int min_rx = lx;
      fill(cnt.begin(), cnt.end(), 0);
      for(int i = 0; i < n; i++){
        maximize(min_rx, xdot[i] + (xdot[i] < lx ? d : 0));
        cnt[ydot[i]]++;
      }
      iota(nxt.begin(), nxt.end(), max_gap = 1);
      iota(pre.begin(), pre.end(), -1);
      pre[nxt[d] = 0] = d;
      for(int i = 0; i < (d << 1); i++){
        event[i].clear();
      }
      for(int i = 0; i < m; i++){
        cnt[yline[i]]++;
        event[xline[i] + (xline[i] < lx ? d : 0)].push_back(i);
      }
      for(int i = 0; i < d; i++){
        if(cnt[i] == 0){
          remove(i);
        }
      }
      for(int rx = lx; rx < lx + d; rx++){
        for(int& i : event[rx]){
          if(--cnt[yline[i]] == 0){
            remove(yline[i]);
          }
        }
        if(rx >= min_rx){
          minimize(ans, (rx - lx + 1) * min(d - max_gap + 1, pre[d] - nxt[d] + 1));
        }
      }
    }
    cout << ans;
  }
}
namespace sub6{
  int max_gap, pre[lim_d], nxt[lim_d], rem_pos[lim_d];
  vector<int>event_rem[lim_d << 1], event_line[lim_d << 1];
  bitset<lim_d>event_dot;
  void remove(int x){
    nxt[pre[x]] = nxt[x];
    pre[nxt[x]] = pre[x];
    if(nxt[x] != d && pre[x] != d){
      maximize(max_gap, nxt[x] - pre[x]);
    }
  }
  void solve(){
    memset(rem_pos, -1, sizeof(rem_pos));
    int min_rx = *max_element(xdot.begin(), xdot.end());
    event_dot.reset();
    for(int i = 0; i < n; i++){
      event_dot[xdot[i]] = true;
      rem_pos[ydot[i]] = d << 1;
    }
    for(int i = 0; i < m; i++){
      maximize(rem_pos[yline[i]], xline[i]);
      event_line[xline[i]].push_back(i);
    }
    for(int lx = 0; lx < d; lx++){
      iota(nxt, nxt + d + 1, max_gap = 1);
      iota(pre, pre + d + 1, -1);
      pre[nxt[d] = 0] = d;
      for(int i = 0; i < (d << 1); i++){
        event_rem[i].clear();
      }
      for(int i = 0; i < d; i++){
        if(rem_pos[i] == -1){
          remove(i);
        }
        else{
          event_rem[rem_pos[i]].push_back(i);
        }
      }
      for(int rx = lx; rx < lx + d; rx++){
        for(int& i : event_rem[rx]){
          remove(i);
        }
        if(rx >= min_rx){
          minimize(ans, (rx - lx + 1) * min(d - max_gap + 1, pre[d] - nxt[d] + 1));
        }
      }
      if(event_dot[lx]){
        min_rx = lx + d;
      }
      for(int& i : event_line[lx]){
        maximize(rem_pos[yline[i]], lx + d);
      }
    }
    cout << ans;    
  }
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
  cin >> n >> m >> d;
  xdot.resize(n);
  ydot.resize(n);
  xline.resize(m);
  yline.resize(m);
  for(int i = 0; i < n; i++){
    cin >> xdot[i] >> ydot[i];
  }
  for(int i = 0; i < m; i++){
    cin >> xline[i] >> yline[i];
  }
  if(m <= 8){
    sub1::solve();
  }
  else if(d <= 100 && n + m <= 5000){
    sub234::solve();
  }
  else if(n + m <= 5000){
    sub5::solve();
  }
  else{
    sub6::solve();
  }
}

Compilation message (stderr)

garden.cpp: In function 'int main()':
garden.cpp:200:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  200 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#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...