답안 #925522

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
925522 2024-02-11T22:25:35 Z myst6 Pairs (IOI07_pairs) C++14
100 / 100
725 ms 9980 KB
#include <bits/stdc++.h>

using namespace std;
using ll = long long;

struct BIT {
  vector<int> value;
  BIT(int size) { value.resize(size); }
  void update(int i, int x) {
    while (i < value.size()) {
      value[i] += x;
      i += i & (-i);
    }
  }
  int query(int i) {
    int sum = 0;
    while (i > 0) {
      sum += value[i];
      i -= i & (-i);
    }
    return sum;
  }
  int query(int l, int r) {
    return query(min((int)value.size()-1, r)) - query(max(0, l-1));
  }
};

struct BIT2 {
  vector<BIT> value;
  BIT2(int size, int size2) { value.resize(size, BIT(size2)); } 
  void update(int i, int j, int x) {
    while (i < value.size()) {
      value[i].update(j, x);
      i += i & (-i);
    }
  }
  int query(int i, int jl, int jr) {
    int sum = 0;
    while (i > 0) {
      sum += value[i].query(jl, jr);
      i -= i & (-i);
    }
    return sum;
  }
  int query(int il, int ir, int jl, int jr) {
    return query(min((int)value.size()-1, ir), jl, jr) - query(max(0, il-1), jl, jr);
  }
};

int main() {
  int B, N, D, M;
  cin >> B >> N >> D >> M;
  if (B == 1) {
    vector<array<int,2>> events;
    for (int i=0; i<N; i++) {
      int X;
      cin >> X;
      events.push_back({X+D+1, -1});
      events.push_back({X, 0});
      events.push_back({X-D-1, +1});
    }
    sort(events.begin(), events.end());
    ll ans = 0;
    int curr = 0;
    for (array<int,2> ev : events) {
      if (ev[1] == 0) {
        ans += curr - 1;
      } else {
        curr += ev[1];
      }
    }
    cout << ans/2 << "\n";
  } else if (B == 2) {
    // when B=2, need to convert coordinates to (x-y, x+y)
    // add event x-y-D, query event x-y, remove event x-y+D
    // add/remove point at (x+y)
    // maintain fenwick tree and query range [x+y-D, x+y+D]
    BIT tree(M+M+1);
    vector<array<int,3>> events;
    for (int i=0; i<N; i++) {
      int X, Y;
      cin >> X >> Y;
      events.push_back({X-Y+D+1, -1, X+Y});
      events.push_back({X-Y, 0, X+Y});
      events.push_back({X-Y-D-1, +1, X+Y});
    }
    sort(events.begin(), events.end());
    ll ans = 0;
    for (array<int,3> ev : events) {
      if (ev[1] == 0) {
        ans += tree.query(ev[2]-D, ev[2]+D) - 1;
      } else {
        tree.update(ev[2], ev[1]);
      }
    }
    cout << ans/2 << "\n";
  } else {
    // when B=3, can store in 2D fenwick trees
    //           and do 2D range querying on row in certain box
    //           after converting coordinates to (x-y, x+y)
    // O(M^3) memory ~ 14MB which is defo fine
    // O(N*M*log(2M+1)^2) time ~ 4 seconds which might not be fine (but hopeflly)
    vector<BIT2> tree(M+1, BIT2(M+M+1, M+M+1));
    vector<array<int,3>> coords;
    for (int i=0; i<N; i++) {
      int X, Y, Z;
      cin >> X >> Y >> Z;
      tree[Z].update(X-Y+M, X+Y, +1);
      coords.push_back({X, Y, Z});
    }
    ll ans = 0;
    for (array<int,3> coord : coords) {
      int X = coord[0], Y = coord[1], Z = coord[2];
      for (int i=max(1, Z-D); i<=min(M, Z+D); i++) {
        int width = D - abs(Z - i);
        ans += tree[i].query(X-Y+M-width, X-Y+M+width, X+Y-width, X+Y+width);
      }
      ans -= 1;
    }
    cout << ans/2 << "\n";
  }
  return 0;
}

Compilation message

pairs.cpp: In member function 'void BIT::update(int, int)':
pairs.cpp:10:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   10 |     while (i < value.size()) {
      |            ~~^~~~~~~~~~~~~~
pairs.cpp: In member function 'void BIT2::update(int, int, int)':
pairs.cpp:32:14: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<BIT>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   32 |     while (i < value.size()) {
      |            ~~^~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 344 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 348 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 41 ms 4812 KB Output is correct
2 Correct 40 ms 5068 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 50 ms 5324 KB Output is correct
2 Correct 53 ms 6128 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 52 ms 6604 KB Output is correct
2 Correct 56 ms 6604 KB Output is correct
3 Correct 55 ms 5324 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 1116 KB Output is correct
2 Correct 1 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 68 ms 8400 KB Output is correct
2 Correct 66 ms 6856 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 75 ms 6708 KB Output is correct
2 Correct 73 ms 6596 KB Output is correct
3 Correct 72 ms 8384 KB Output is correct
4 Correct 71 ms 6848 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 78 ms 8900 KB Output is correct
2 Correct 77 ms 7872 KB Output is correct
3 Correct 84 ms 8288 KB Output is correct
4 Correct 83 ms 7616 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 8 ms 7772 KB Output is correct
2 Correct 6 ms 7640 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 45 ms 2004 KB Output is correct
2 Correct 63 ms 2004 KB Output is correct
3 Correct 44 ms 2504 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 208 ms 5880 KB Output is correct
2 Correct 532 ms 6612 KB Output is correct
3 Correct 209 ms 6648 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 533 ms 9376 KB Output is correct
2 Correct 725 ms 9976 KB Output is correct
3 Correct 267 ms 9980 KB Output is correct