Problem p00129 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1},
          dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

struct P {
  P() {}
  P(ll _r, ll _i) : r(_r), i(_i) {}
  void real(const ll &v) { r = v; }
  void imag(const ll &v) { i = v; }
  ll r, i;
};

ll real(const P &p) { return p.r; }
ll imag(const P &p) { return p.i; }
ll norm(const P &p) {
  ll r = real(p), i = imag(p);
  return r * r + i * i;
}

P operator+(const P &lhs, const P &rhs) {
  return P(real(lhs) + real(rhs), imag(lhs) + imag(rhs));
}
P operator-(const P &lhs, const P &rhs) {
  return P(real(lhs) - real(rhs), imag(lhs) - imag(rhs));
}
P operator-(const P &p) { return P(-real(p), -imag(p)); }

ll cross(const P &lhs, const P &rhs) {
  return real(lhs) * imag(rhs) - imag(lhs) * real(rhs);
}

ll dot(const P &lhs, const P &rhs) {
  return real(lhs) * real(rhs) + imag(lhs) * imag(rhs);
}

ll distance(const P &a, const P &b, const P &p) {
  ll c = cross(p - a, b - a);
  return c * c;
}

bool doesLineCrossCircle(const P &a, const P &b, const P &cc,
                         const ll &radius) {
  if (distance(a, b, cc) > radius * radius * norm(b - a)) {
    return false;
  }
  if (norm(a - cc) > radius * radius && norm(b - cc) > radius * radius) {
    return dot(cc - a, b - a) * dot(cc - b, b - a) <= 0;
  }
  return (norm(a - cc) < radius * radius) ^ (norm(b - cc) < radius * radius);
}

int N, M;
P wps[100100];
ll wrs[100100];

int main() {
  while (std::cin >> N, N) {
    assert(N < 100100);
    REP(i, N) {
      ll re, im;
      std::cin >> re >> im >> wrs[i];

      wps[i].real(re);
      wps[i].imag(im);
    }

    std::cin >> M;

    REP(i, M) {
      P taro, oni;
      ll re, im;
      std::cin >> re >> im;
      taro.real(re);
      taro.imag(im);
      std::cin >> re >> im;
      oni.real(re);
      oni.imag(im);

      bool f = false;
      REP(j, N) {
        assert(norm(taro - wps[j]) != wrs[j] * wrs[j] &&
               norm(oni - wps[j]) != wrs[j] * wrs[j]);
        if (real(taro) == real(oni) && imag(taro) == imag(oni)) {
          continue;
        }
        if (doesLineCrossCircle(taro, oni, wps[j], wrs[j])) {
          f = true;
        }
      }

      if (f) {
        puts("Safe");
      } else {
        puts("Danger");
      }
    }
  }
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1},
          dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

struct P {
  P() {}
  P(ll _r, ll _i) : r(_r), i(_i) {}
  void real(const ll &v) { r = v; }
  void imag(const ll &v) { i = v; }
  ll r, i;
};

ll real(const P &p) { return p.r; }
ll imag(const P &p) { return p.i; }
ll norm(const P &p) {
  ll r = real(p), i = imag(p);
  return r * r + i * i;
}

P operator+(const P &lhs, const P &rhs) {
  return P(real(lhs) + real(rhs), imag(lhs) + imag(rhs));
}
P operator-(const P &lhs, const P &rhs) {
  return P(real(lhs) - real(rhs), imag(lhs) - imag(rhs));
}
P operator-(const P &p) { return P(-real(p), -imag(p)); }

ll cross(const P &lhs, const P &rhs) {
  return real(lhs) * imag(rhs) - imag(lhs) * real(rhs);
}

ll dot(const P &lhs, const P &rhs) {
  return real(lhs) * real(rhs) + imag(lhs) * imag(rhs);
}

ll distance(const P &a, const P &b, const P &p) {
  ll c = cross(p - a, b - a);
  return c * c;
}

bool doesLineCrossCircle(const P &a, const P &b, const P &cc,
                         const ll &radius) {
  if (distance(a, b, cc) > radius * radius * norm(b - a)) {
    return false;
  }
  if (norm(a - cc) > radius * radius && norm(b - cc) > radius * radius) {
    return dot(cc - a, b - a) * dot(cc - b, b - a) <= 0;
  }
  return (norm(a - cc) < radius * radius) ^ (norm(b - cc) < radius * radius);
}

int N, M;
P wps[100100];
ll wrs[100100];

int main() {
  while (std::cin >> N, N) {
    assert(N < 100100);
    REP(i, N) {
      ll re, im;
      std::cin >> re >> im >> wrs[i];

      wps[i].real(re);
      wps[i].imag(im);
    }

    std::cin >> M;

    REP(i, M) {
      P taro, oni;
      ll re, im;
      std::cin >> re >> im;
      taro.real(re);
      taro.imag(im);
      std::cin >> re >> im;
      oni.real(re);
      oni.imag(im);

      bool f = false;
      REP(j, N) {
        // assert(norm(taro-wps[j]) != wrs[j] * wrs[j] &&
        //       norm(oni-wps[j]) != wrs[j] * wrs[j]);
        if (real(taro) == real(oni) && imag(taro) == imag(oni)) {
          continue;
        }
        if (doesLineCrossCircle(taro, oni, wps[j], wrs[j])) {
          f = true;
        }
      }

      if (f) {
        puts("Safe");
      } else {
        puts("Danger");
      }
    }
  }
}