#include using namespace std; using ll = long long; static constexpr int MAXN = 200016; static constexpr int MAXQ = 200005; // v[0..2] : U // v[3..5] : L alignas(64) static ll v[6][MAXN]; // それぞれの単調スタック用 Union-Find alignas(64) static int parent_[6][MAXN]; alignas(64) static int stk[6][MAXN]; struct Query { int s; int l; int next; }; static Query qs[MAXQ]; static int head[MAXN]; static unsigned char ans[MAXQ]; class FastScanner { static constexpr int SZ = 1 << 20; char buf[SZ]; int ptr = 0; int len = 0; inline char getChar() { if (ptr == len) { len = (int)fread(buf, 1, SZ, stdin); ptr = 0; if (len == 0) return 0; } return buf[ptr++]; } public: inline ll nextLong() { char c = getChar(); while (c <= ' ') c = getChar(); bool neg = false; if (c == '-') { neg = true; c = getChar(); } ll x = 0; while ('0' <= c && c <= '9') { x = x * 10 + (c - '0'); c = getChar(); } return neg ? -x : x; } inline int nextInt() { return (int)nextLong(); } }; template inline int findRoot(int x) { // path halving while (parent_[K][x] != x) { parent_[K][x] = parent_[K][parent_[K][x]]; x = parent_[K][x]; } return x; } template inline void addMin(int i, int& top) { parent_[K][i] = i; const ll x = v[K][i]; while (top && v[K][stk[K][top - 1]] > x) { const int p = stk[K][--top]; parent_[K][p] = i; } stk[K][top++] = i; } template inline void addMax(int i, int& top) { parent_[K][i] = i; const ll x = v[K][i]; while (top && v[K][stk[K][top - 1]] < x) { const int p = stk[K][--top]; parent_[K][p] = i; } stk[K][top++] = i; } int main() { FastScanner fs; const int N = fs.nextInt(); for (int i = 0; i < N; ++i) { const ll A = fs.nextLong(); const ll B = fs.nextLong(); const ll D = fs.nextLong(); const ll u0 = A + B; const ll u1 = B - A; const ll u2 = B; v[0][i] = u0; v[1][i] = u1; v[2][i] = u2; v[3][i] = u0 - 2 * D; v[4][i] = u1 - 2 * D; v[5][i] = u2 - D; } fill(head, head + N, -1); const int Q = fs.nextInt(); for (int q = 0; q < Q; ++q) { const int s = fs.nextInt() - 1; const int l = fs.nextInt() - 1; const int r = fs.nextInt() - 1; qs[q].s = s; qs[q].l = l; // 右端 r の linked list に追加 qs[q].next = head[r]; head[r] = q; } int top0 = 0; int top1 = 0; int top2 = 0; int top3 = 0; int top4 = 0; int top5 = 0; for (int r = 0; r < N; ++r) { // U 側は区間 minimum addMin<0>(r, top0); addMin<1>(r, top1); addMin<2>(r, top2); // L 側は区間 maximum addMax<3>(r, top3); addMax<4>(r, top4); addMax<5>(r, top5); // 右端が r の全クエリを処理 for (int qi = head[r]; qi != -1; qi = qs[qi].next) { const int s = qs[qi].s; const int l = qs[qi].l; // short-circuit するので、 // No になりやすいケースでは6回全部 find しない。 const bool ok = v[0][findRoot<0>(l)] > v[3][s] && v[3][findRoot<3>(l)] < v[0][s] && v[1][findRoot<1>(l)] > v[4][s] && v[4][findRoot<4>(l)] < v[1][s] && v[2][findRoot<2>(l)] > v[5][s] && v[5][findRoot<5>(l)] < v[2][s]; ans[qi] = (unsigned char)ok; } } // 出力もまとめて fwrite static char out[MAXQ * 4 + 16]; char* p = out; for (int i = 0; i < Q; ++i) { if (ans[i]) { *p++ = 'Y'; *p++ = 'e'; *p++ = 's'; *p++ = '\n'; } else { *p++ = 'N'; *p++ = 'o'; *p++ = '\n'; } } fwrite(out, 1, p - out, stdout); return 0; }