제출 #1342515

#제출 시각아이디문제언어결과실행 시간메모리
1342515avighnaIOI 바이러스 (JOI21_fever)C++20
0 / 100
1 ms344 KiB
#include <bits/stdc++.h>

using namespace std;

struct point {
  int x, y;
};

enum dir {
  RIGHT,
  LEFT,
  UP,
  DOWN
};

enum linetype {
  X_PLUS_Y,
  X_MINUS_Y
};

enum onwhat {
  ON_X,
  ON_Y
};

struct maptype {
  linetype linetyp;
  onwhat onwha;
  dir direction;
  bool operator<(const maptype &r) const {
    if (linetyp != r.linetyp) {
      return linetyp < r.linetyp;
    }
    if (onwha != r.onwha) {
      return onwha < r.onwha;
    }
    return direction < r.direction;
  }
};

int solve(int n, vector<point> a) {
  vector<dir> dirs = {RIGHT};
  for (int i = 1; i < n; ++i) {
    auto [x, y] = a[i];
    if (x >= 0 && y >= 0) {
      dirs.push_back(y < x ? LEFT : DOWN);
    } else if (x >= 0 && y < 0) {
      dirs.push_back(x > -y ? LEFT : UP);
    } else if (x < 0 && y >= 0) {
      dirs.push_back(y > -x ? DOWN : RIGHT);
    } else {
      dirs.push_back(-y > -x ? UP : RIGHT);
    }
  }

  map<maptype, map<int, set<pair<int, int>>>> mps;
  for (int i = 0; i < n; ++i) {
    auto [x, y] = a[i];
    mps[{X_MINUS_Y, ON_X, dirs[i]}][x - y].insert({x, i});
    mps[{X_MINUS_Y, ON_Y, dirs[i]}][x - y].insert({y, i});
    mps[{X_PLUS_Y, ON_X, dirs[i]}][x + y].insert({x, i});
    mps[{X_PLUS_Y, ON_Y, dirs[i]}][x + y].insert({y, i});
  }

  priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
  pq.push({0, 0});
  vector<int> vis(n);
  while (!pq.empty()) {
    auto [t, i] = pq.top();
    pq.pop();
    if (vis[i]) {
      continue;
    }
    vis[i] = 1;
    vector<int> rem;
    auto [x, y] = a[i];
    auto add = [&](int dist, std::set<std::pair<int, int>>::iterator it) {
      rem.push_back(it->second);
      pq.push({t + dist, it->second});
    };
    if (dirs[i] == RIGHT) {
      // on line x-y with their y >= our y
      auto &st1 = mps[{X_MINUS_Y, ON_Y, DOWN}][x - y];
      for (auto it = st1.lower_bound({y, -1}); it != st1.end(); ++it) {
        add(it->first - y, it);
      }
      // on line x+y with their y <= our y
      auto &st2 = mps[{X_PLUS_Y, ON_Y, UP}][x + y];
      for (auto it = st2.begin(), it2 = st2.upper_bound({y, n}); it != it2; ++it) {
        add(y - it->first, it);
      }
    } else if (dirs[i] == DOWN) {
      // on line x-y with their x <= our x
      auto &st1 = mps[{X_MINUS_Y, ON_X, RIGHT}][x - y];
      for (auto it = st1.begin(), it2 = st1.upper_bound({x, n}); it != it2; ++it) {
        add(x - it->first, it);
      }
      // on line x+y with their x >= our x
      auto &st2 = mps[{X_PLUS_Y, ON_X, LEFT}][x + y];
      for (auto it = st2.lower_bound({x, -1}); it != st2.end(); ++it) {
        add(it->first - x, it);
      }
    } else if (dirs[i] == LEFT) {
      // on line x+y with their y >= our y
      auto &st1 = mps[{X_PLUS_Y, ON_Y, DOWN}][x + y];
      for (auto it = st1.lower_bound({y, -1}); it != st1.end(); ++it) {
        add(it->first - y, it);
      }
      // on line x-y with their y <= our y
      auto &st2 = mps[{X_MINUS_Y, ON_Y, UP}][x - y];
      for (auto it = st2.begin(), it2 = st2.upper_bound({y, n}); it != it2; ++it) {
        add(y - it->first, it);
      }
    } else { // UP
      // on line x-y with their x >= our x
      auto &st1 = mps[{X_MINUS_Y, ON_X, LEFT}][x - y];
      for (auto it = st1.lower_bound({x, -1}); it != st1.end(); ++it) {
        add(it->first - x, it);
      }
      // on line x+y with their x <= our x
      auto &st2 = mps[{X_PLUS_Y, ON_X, RIGHT}][x + y];
      for (auto it = st2.begin(), it2 = st2.upper_bound({x, n}); it != it2; ++it) {
        add(x - it->first, it);
      }
    }
    for (auto &mp : mps) {
      for (int &i : rem) {
        auto [x, y] = a[i];
        if (mp.first.linetyp == X_PLUS_Y) {
          if (mp.first.onwha == ON_X) {
            mp.second[x + y].erase({x, i});
          } else {
            mp.second[x + y].erase({y, i});
          }
        } else {
          if (mp.first.onwha == ON_X) {
            mp.second[x - y].erase({x, i});
          } else {
            mp.second[x - y].erase({y, i});
          }
        }
      }
    }
  }
  return accumulate(vis.begin(), vis.end(), 0);
}

int main() {
  cin.tie(nullptr)->sync_with_stdio(false);

  int n;
  cin >> n;
  vector<point> a(n);
  for (auto &[x, y] : a) {
    cin >> x >> y;
  }
  for (auto &[x, y] : a | views::drop(1)) {
    x -= a[0].x, y -= a[0].y;
  }
  a[0] = {0, 0};

  auto rotate = [&]() {
    for (auto &[x, y] : a) {
      int nx = y, ny = -x;
      x = nx, y = ny;
    }
  };

  int ans = solve(n, a);
  rotate();
  ans = max(ans, solve(n, a));
  rotate();
  ans = max(ans, solve(n, a));
  rotate();
  ans = max(ans, solve(n, a));

  cout << ans << '\n';
}
#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...