#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
// - Dữ kiện quan trọng: x(u) = -1 hoặc 1
// - Nhận xét:
// Xét một đoạn con bất kì trên đường đi từ u đến v có tổng là sum,
// với mỗi thao tác bổ sung một đỉnh vào đoạn hoặc xoá một đỉnh khỏi đoạn, giá trị của sum tăng/giảm 1 đơn vị
// => Giá trị của sum là liên tục
// => Nếu ta biết được giá trị của đoạn con có tổng lớn nhất (mx_sub) và đoạn con có tổng nhỏ nhất (mn_sub), thì một giá trị k bất kì
// thoả mãn tồn tại một đoạn con trên đường đi từ u đến v có tổng bằng k nếu k thuộc đoạn [mn_sub, mx_sub]
// => Với mỗi truy vấn, thay vì tìm đoạn con có tổng = k (một bài toán khó giải quyết hơn),
// ta đi tìm đoạn con có tổng lớn nhất và đoạn con có tổng nhỏ nhất trên đường đi từ u đến v rồi kiểm tra k có thuộc đoạn này không
// - Lưu ý hàm combine() trong bài này không có tính chất giao hoán nên cần xử lí theo đúng chiều đường đi từ u đến v
const int N = 2e5 + 5;
const int LOG = 18;
int n, q;
int x[N];
struct Data {
int mx_sub, mx_pref, mx_suf; // max subarray sum/max prefix sum/max suffix sum
int mn_sub, mn_pref, mn_suf; // min subarray sum/min prefix sum/min suffix sum
int sum; // total sum
Data(int x = 0) {
mx_sub = mx_pref = mx_suf = max(0, x);
mn_sub = mn_pref = mn_suf = min(0, x);
sum = x;
}
};
Data combine(const Data& a, const Data& b) {
Data ans;
ans.mx_sub = max({a.mx_sub, b.mx_sub, a.mx_suf + b.mx_pref});
ans.mx_pref = max(a.mx_pref, a.sum + b.mx_pref);
ans.mx_suf = max(b.mx_suf, b.sum + a.mx_suf);
ans.mn_sub = min({a.mn_sub, b.mn_sub, a.mn_suf + b.mn_pref});
ans.mn_pref = min(a.mn_pref, a.sum + b.mn_pref);
ans.mn_suf = min(b.mn_suf, b.sum + a.mn_suf);
ans.sum = a.sum + b.sum;
return ans;
}
int up[LOG][N];
Data f[LOG][N];
int depth[N];
int lca(int u, int v) {
if (depth[u] < depth[v]) swap(u, v);
int diff = depth[u] - depth[v];
for (int i = 0; i < LOG; i++) {
if ((diff >> i) & 1) {
u = up[i][u];
}
}
if (u == v) return u;
for (int i = LOG - 1; i >= 0; i--) {
if (up[i][u] != up[i][v]) {
u = up[i][u];
v = up[i][v];
}
}
return up[0][u];
}
Data query(int u, int anc) {
int diff = depth[u] - depth[anc];
Data ans;
for (int i = 0; i < LOG; i++) {
if ((diff >> i) & 1) {
ans = combine(ans, f[i][u]);
u = up[i][u];
}
}
return ans;
}
void solve() {
cin >> q;
n = 1;
x[1] = 1;
depth[1] = 0;
up[0][1] = 1;
f[0][1] = Data(x[1]);
for (int i = 0; i < q; i++) {
char type; cin >> type;
if (type == '+') {
int u, v = ++n;
cin >> u >> x[v];
depth[v] = depth[u] + 1;
up[0][v] = u;
f[0][v] = Data(x[v]);
for (int i = 1; i < LOG; i++) {
up[i][v] = up[i - 1][up[i - 1][v]];
f[i][v] = combine(f[i - 1][v], f[i - 1][up[i - 1][v]]);
}
}
else {
int u, v, k;
cin >> u >> v >> k;
// u -> lca_uv -> v
int lca_uv = lca(u, v);
Data ans = combine(query(u, lca_uv), Data(x[lca_uv]));
Data other = query(v, lca_uv);
swap(other.mx_pref, other.mx_suf);
swap(other.mn_pref, other.mn_suf);
ans = combine(ans, other);
cout << ((ans.mn_sub <= k && k <= ans.mx_sub) ? "YES" : "NO") << '\n';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t; cin >> t;
while (t--) {
solve();
}
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+IAoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsgIAoKdHlwZWRlZiBsb25nIGxvbmcgbGw7ICAKdHlwZWRlZiBwYWlyPGludCwgaW50PiBpaTsgIAoKY29uc3QgaW50IElORiA9IDFlOTsgIApjb25zdCBsbCBMSU5GID0gMWUxODsgIAoKLy8gLSBE4buvIGtp4buHbiBxdWFuIHRy4buNbmc6IHgodSkgPSAtMSBob+G6t2MgMQovLyAtIE5o4bqtbiB4w6l0OgovLyAgIFjDqXQgbeG7mXQgxJFv4bqhbiBjb24gYuG6pXQga8OsIHRyw6puIMSRxrDhu51uZyDEkWkgdOG7qyB1IMSR4bq/biB2IGPDsyB04buVbmcgbMOgIHN1bSwgCi8vICAgduG7m2kgbeG7l2kgdGhhbyB0w6FjIGLhu5Ugc3VuZyBt4buZdCDEkeG7iW5oIHbDoG8gxJFv4bqhbiBob+G6t2MgeG/DoSBt4buZdCDEkeG7iW5oIGto4buPaSDEkW/huqFuLCBnacOhIHRy4buLIGPhu6dhIHN1bSB0xINuZy9naeG6o20gMSDEkcahbiB24buLCi8vID0+IEdpw6EgdHLhu4sgY+G7p2Egc3VtIGzDoCBsacOqbiB04bulYwovLyA9PiBO4bq/dSB0YSBiaeG6v3QgxJHGsOG7o2MgZ2nDoSB0cuG7iyBj4bunYSDEkW/huqFuIGNvbiBjw7MgdOG7lW5nIGzhu5tuIG5o4bqldCAobXhfc3ViKSB2w6AgxJFv4bqhbiBjb24gY8OzIHThu5VuZyBuaOG7jyBuaOG6pXQgKG1uX3N1YiksIHRow6wgbeG7mXQgZ2nDoSB0cuG7iyBrIGLhuqV0IGvDrCAKLy8gICAgdGhv4bqjIG3Do24gdOG7k24gdOG6oWkgbeG7mXQgxJFv4bqhbiBjb24gdHLDqm4gxJHGsOG7nW5nIMSRaSB04burIHUgxJHhur9uIHYgY8OzIHThu5VuZyBi4bqxbmcgayBu4bq/dSBrIHRodeG7mWMgxJFv4bqhbiBbbW5fc3ViLCBteF9zdWJdIAovLyA9PiBW4bubaSBt4buXaSB0cnV5IHbhuqVuLCB0aGF5IHbDrCB0w6xtIMSRb+G6oW4gY29uIGPDsyB04buVbmcgPSBrICht4buZdCBiw6BpIHRvw6FuIGtow7MgZ2nhuqNpIHF1eeG6v3QgaMahbiksCi8vICAgIHRhIMSRaSB0w6xtIMSRb+G6oW4gY29uIGPDsyB04buVbmcgbOG7m24gbmjhuqV0IHbDoCDEkW/huqFuIGNvbiBjw7MgdOG7lW5nIG5o4buPIG5o4bqldCB0csOqbiDEkcaw4budbmcgxJFpIHThu6sgdSDEkeG6v24gdiBy4buTaSBraeG7g20gdHJhIGsgY8OzIHRodeG7mWMgxJFv4bqhbiBuw6B5IGtow7RuZwovLyAtIEzGsHUgw70gaMOgbSBjb21iaW5lKCkgdHJvbmcgYsOgaSBuw6B5IGtow7RuZyBjw7MgdMOtbmggY2jhuqV0IGdpYW8gaG/DoW4gbsOqbiBj4bqnbiB44butIGzDrSB0aGVvIMSRw7puZyBjaGnhu4F1IMSRxrDhu51uZyDEkWkgdOG7qyB1IMSR4bq/biB2CgkJCQpjb25zdCBpbnQgTiA9IDJlNSArIDU7IApjb25zdCBpbnQgTE9HID0gMTg7ICAKCmludCBuLCBxOyAKaW50IHhbTl07IAoKc3RydWN0IERhdGEgewoJaW50IG14X3N1YiwgbXhfcHJlZiwgbXhfc3VmOyAvLyBtYXggc3ViYXJyYXkgc3VtL21heCBwcmVmaXggc3VtL21heCBzdWZmaXggc3VtCglpbnQgbW5fc3ViLCBtbl9wcmVmLCBtbl9zdWY7IC8vIG1pbiBzdWJhcnJheSBzdW0vbWluIHByZWZpeCBzdW0vbWluIHN1ZmZpeCBzdW0KCWludCBzdW07IC8vIHRvdGFsIHN1bQoJCglEYXRhKGludCB4ID0gMCkgewoJCW14X3N1YiA9IG14X3ByZWYgPSBteF9zdWYgPSBtYXgoMCwgeCk7ICAgCgkJbW5fc3ViID0gbW5fcHJlZiA9IG1uX3N1ZiA9IG1pbigwLCB4KTsgCgkJc3VtID0geDsgIAoJfQp9OwoKRGF0YSBjb21iaW5lKGNvbnN0IERhdGEmIGEsIGNvbnN0IERhdGEmIGIpIHsKCURhdGEgYW5zOyAgCglhbnMubXhfc3ViID0gbWF4KHthLm14X3N1YiwgYi5teF9zdWIsIGEubXhfc3VmICsgYi5teF9wcmVmfSk7IAoJYW5zLm14X3ByZWYgPSBtYXgoYS5teF9wcmVmLCBhLnN1bSArIGIubXhfcHJlZik7ICAKCWFucy5teF9zdWYgPSBtYXgoYi5teF9zdWYsIGIuc3VtICsgYS5teF9zdWYpOyAKCWFucy5tbl9zdWIgPSBtaW4oe2EubW5fc3ViLCBiLm1uX3N1YiwgYS5tbl9zdWYgKyBiLm1uX3ByZWZ9KTsgIAoJYW5zLm1uX3ByZWYgPSBtaW4oYS5tbl9wcmVmLCBhLnN1bSArIGIubW5fcHJlZik7CglhbnMubW5fc3VmID0gbWluKGIubW5fc3VmLCBiLnN1bSArIGEubW5fc3VmKTsgCglhbnMuc3VtID0gYS5zdW0gKyBiLnN1bTsKCXJldHVybiBhbnM7IAp9CgppbnQgdXBbTE9HXVtOXTsKRGF0YSBmW0xPR11bTl07ICAKaW50IGRlcHRoW05dOyAKCmludCBsY2EoaW50IHUsIGludCB2KSB7CglpZiAoZGVwdGhbdV0gPCBkZXB0aFt2XSkgc3dhcCh1LCB2KTsKCWludCBkaWZmID0gZGVwdGhbdV0gLSBkZXB0aFt2XTsgCglmb3IgKGludCBpID0gMDsgaSA8IExPRzsgaSsrKSB7CgkJaWYgKChkaWZmID4+IGkpICYgMSkgewoJCQl1ID0gdXBbaV1bdV07IAoJCX0KCX0gCglpZiAodSA9PSB2KSByZXR1cm4gdTsgCglmb3IgKGludCBpID0gTE9HIC0gMTsgaSA+PSAwOyBpLS0pIHsKCQlpZiAodXBbaV1bdV0gIT0gdXBbaV1bdl0pIHsKCQkJdSA9IHVwW2ldW3VdOyAKCQkJdiA9IHVwW2ldW3ZdOwoJCX0KCX0KCXJldHVybiB1cFswXVt1XTsgCn0KCkRhdGEgcXVlcnkoaW50IHUsIGludCBhbmMpIHsKCWludCBkaWZmID0gZGVwdGhbdV0gLSBkZXB0aFthbmNdOyAKCURhdGEgYW5zOyAgCglmb3IgKGludCBpID0gMDsgaSA8IExPRzsgaSsrKSB7CgkJaWYgKChkaWZmID4+IGkpICYgMSkgewoJCQlhbnMgPSBjb21iaW5lKGFucywgZltpXVt1XSk7IAoJCQl1ID0gdXBbaV1bdV07IAoJCX0KCX0KCXJldHVybiBhbnM7IAp9Cgp2b2lkIHNvbHZlKCkgewoJY2luID4+IHE7IAoJbiA9IDE7ICAKCXhbMV0gPSAxOyAKCWRlcHRoWzFdID0gMDsgIAoJdXBbMF1bMV0gPSAxOyAKCWZbMF1bMV0gPSBEYXRhKHhbMV0pOyAKCWZvciAoaW50IGkgPSAwOyBpIDwgcTsgaSsrKSB7CgkJY2hhciB0eXBlOyBjaW4gPj4gdHlwZTsgCgkJaWYgKHR5cGUgPT0gJysnKSB7CgkJCWludCB1LCB2ID0gKytuOyAgIAoJCQljaW4gPj4gdSA+PiB4W3ZdOyAKCQkJZGVwdGhbdl0gPSBkZXB0aFt1XSArIDE7ICAKCQkJdXBbMF1bdl0gPSB1OyAgCgkJCWZbMF1bdl0gPSBEYXRhKHhbdl0pOyAKCQkJZm9yIChpbnQgaSA9IDE7IGkgPCBMT0c7IGkrKykgewoJCQkJdXBbaV1bdl0gPSB1cFtpIC0gMV1bdXBbaSAtIDFdW3ZdXTsgCgkJCQlmW2ldW3ZdID0gY29tYmluZShmW2kgLSAxXVt2XSwgZltpIC0gMV1bdXBbaSAtIDFdW3ZdXSk7IAoJCQl9CgkJfQoJCWVsc2UgewoJCQlpbnQgdSwgdiwgazsgCgkJCWNpbiA+PiB1ID4+IHYgPj4gazsgCgkJCS8vIHUgLT4gbGNhX3V2IC0+IHYKCQkJaW50IGxjYV91diA9IGxjYSh1LCB2KTsgICAKCQkJRGF0YSBhbnMgPSBjb21iaW5lKHF1ZXJ5KHUsIGxjYV91diksIERhdGEoeFtsY2FfdXZdKSk7ICAKCQkJRGF0YSBvdGhlciA9IHF1ZXJ5KHYsIGxjYV91dik7ICAKCQkJc3dhcChvdGhlci5teF9wcmVmLCBvdGhlci5teF9zdWYpOyAKCQkJc3dhcChvdGhlci5tbl9wcmVmLCBvdGhlci5tbl9zdWYpOyAKCQkJYW5zID0gY29tYmluZShhbnMsIG90aGVyKTsgCgkJCWNvdXQgPDwgKChhbnMubW5fc3ViIDw9IGsgJiYgayA8PSBhbnMubXhfc3ViKSA/ICJZRVMiIDogIk5PIikgPDwgJ1xuJzsgCgkJfQoJfQp9CgppbnQgbWFpbigpIHsKCWlvczo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsgCgljaW4udGllKG51bGxwdHIpOyAJCglpbnQgdDsgY2luID4+IHQ7IAoJd2hpbGUgKHQtLSkgewoJCXNvbHZlKCk7IAoJfQp9Cg==