RT.
TLE on test 3.
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/hash_policy.hpp>
#define gt getchar
#define pt putchar
#define re register
typedef long long ll;
const int N=2e5+5;
const int inf=1e9;
using namespace std;
using namespace __gnu_pbds;
inline bool __(char ch){return ch>=48&&ch<=57;}
inline int read(){
int x=0;bool sgn=0;char ch=gt();
while(!__(ch)&&ch!=EOF) sgn|=(ch=='-'),ch=gt();
while(__(ch)) x=(x<<1)+(x<<3)+(ch&15),ch=gt();
return sgn?-x:x;
}
template<class T> inline void print(T x){
static char st[70];short top=0;
if(x<0) pt('-');
do{st[++top]=x>=0?(x%10+48):(-(x%10)+48),x/=10;}while(x);
while(top) pt(st[top--]);
}
template<class T> inline void printsp(T x){
print(x);
putchar(' ');
}
template<class T> inline void println(T x){
print(x);
putchar('\n');
}
inline void put_str(string s){
int siz=s.size();
for(int i=0;i<siz;++i) pt(s[i]);
printf("\n");
}
int T,n,a[N],u[N],v[N],tot,k[N],val_new[N];
bool flag[N];
char opt;
inline int lson(int x){return x<<1;}
inline int rson(int x){return x<<1|1;}
struct Inform{
int sum,mx,mn;
int lmax,rmax,lmin,rmin;
Inform(){
sum=0;
mx=lmax=rmax=-inf;
mn=lmin=rmin=inf;
}
inline void init(int x){
sum=mx=mn=lmax=rmax=lmin=rmin=x;
}
};
inline Inform operator+(const Inform &a,const Inform &b){
Inform c;
c.sum=a.sum+b.sum;
c.mx=max(max(a.mx,b.mx),a.rmax+b.lmax);
c.mn=min(min(a.mn,b.mn),a.rmin+b.lmin);
c.lmax=max(a.lmax,a.sum+b.lmax);
c.rmax=max(b.rmax,b.sum+a.rmax);
c.lmin=min(a.lmin,a.sum+b.lmin);
c.rmin=min(b.rmin,b.sum+a.rmin);
return c;
}
struct Node{
int l,r;
Inform val;
}node[N<<2];
inline void push_up(int p){
node[p].val=node[lson(p)].val+node[rson(p)].val;
}
void build(int p,int l,int r){
node[p].l=l,node[p].r=r;
if(l==r) return node[p].val.init(val_new[l]);
int mid=l+((r-l)>>1);
build(lson(p),l,mid);
build(rson(p),mid+1,r);
push_up(p);
}
Inform query(int p,int l,int r){
if(l<=node[p].l&&node[p].r<=r) return node[p].val;
int mid=node[p].l+((node[p].r-node[p].l)>>1);
if(r<=mid) return query(lson(p),l,r);
if(l>mid) return query(rson(p),l,r);
return query(lson(p),l,r)+query(rson(p),l,r);
}
struct edge{
int to,nxt;
}e[N<<1];
int head[N],cnt,dep[N],siz[N],son[N],top[N],fa[N],dfn[N],ti;
inline void add_edge(int f,int t){
e[++cnt].to=t;
e[cnt].nxt=head[f];
head[f]=cnt;
}
inline void add_double(int f,int t){
add_edge(f,t);
add_edge(t,f);
}
void dfs1(int u,int fath){
dep[u]=dep[fath]+1;
siz[u]=1,fa[u]=fath;
for(re int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fath) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(!son[u]||siz[son[u]]<siz[v]) son[u]=v;
}
}
void dfs2(int u,int topx){
dfn[u]=++ti,top[u]=topx;
val_new[dfn[u]]=a[u];
if(!son[u]) return;
dfs2(son[u],topx);
for(re int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v!=fa[u]&&v!=son[u]) dfs2(v,v);
}
}
Inform query_range(int x,int y){
Inform L,R;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]){
R=query(1,dfn[top[y]],dfn[y])+R;
y=fa[top[y]];
}else{
L=query(1,dfn[top[x]],dfn[x])+L;
x=fa[top[x]];
}
}
if(dep[x]<dep[y]){
R=query(1,dfn[x],dfn[y])+R;
}else{
L=query(1,dfn[y],dfn[x])+L;
}
swap(L.lmax,L.rmax);
swap(L.lmin,L.rmin);
return L+R;
}
inline void solve(){
n=read(),a[1]=1;
cnt=0,tot=1,ti=0;
for(re int i=1;i<=n;++i) head[i]=son[i]=flag[i]=0;
for(re int i=1;i<=n;++i){
scanf("%c",&opt);
if(opt=='+') u[i]=read(),v[i]=++tot,a[v[i]]=read(),add_double(u[i],v[i]);
else flag[i]=1,u[i]=read(),v[i]=read(),k[i]=read();
}
dfs1(1,0);
dfs2(1,1);
build(1,1,tot);
for(re int i=1;i<=n;++i){
if(flag[i]){
Inform Result=query_range(u[i],v[i]);
int maxx=max(Result.mx,0);
int minn=min(Result.mn,0);
printf((minn<=k[i]&&k[i]<=maxx)?"YES\n":"NO\n");
}
}
}
signed main(){
T=read();
while(T--) solve();
return 0;
}