#line 1 "template.hpp" #include using ll = long long; #define REP(i, n) for(ll i = 0; (i) < ll(n); ++ (i)) #define FOR(i, m, n) for(ll i = (m); (i) <= ll(n); ++ (i)) #define REPR(i, n) for(ll i = ll(n) - 1; (i) >= 0; -- (i)) #define FORR(i, m, n) for(ll i = ll(n); (i) >= ll(m); -- (i)) #define ALL(x) x.begin(),x.end() #define INF (int)1e9 #define LLINF (long long)1e18 #define MOD (int)(1e9+7) #define MOD9 (int)998244353 #define PI 3.141592653589 #define PB push_back #define F first #define S second #define YESNO(T) if(T){cout<<"YES"< > #define CostGraph vector > > #define PII pair #define PLL pair #define VI vector #define VL vector #define VVI vector > #define VVL vector > #define VPII vector > #define VPLL vector > #define DDD fixed< inline bool chmin(T &a, T b) { if(a > b){ a = b; return true;} return false; } template inline bool chmax(T &a, T b) { if(a < b){a = b; return true;} return false; } struct input{ int n; input() {} input(int n_) : n(n_){}; template operator T(){ T ret; std::cin >> ret; return ret; } template operator std::vector() { std::vector ret(n); REP(i,n) std::cin >> ret[i]; return ret; } }; template inline void printVec(std::vector v){ REP(i,v.size()){ if(i) std::cout << " "; std::cout << v[i]; } std::cout << std::endl; } using namespace std; #line 1 "data-structure/segment-tree/segment-tree.hpp" template struct SegmentTree{ using F = function; int sz; vector seg; const F f; const T e; SegmentTree(int n, const F f, const T &e): f(f), e(e){ sz = 1; while(sz < n) sz <<= 1; seg.assign(2 * sz, e); } void set(int k, const T &x){ seg[k+sz] = x; } void build(){ for(int k = sz - 1; k > 0; --k){ seg[k] = f(seg[2*k+0], seg[2*k+1]); } } void update(int k, const T &x){ k += sz; seg[k] = x; while(k >>= 1){ seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]); } } T query(int a, int b){ T l = e, r = e; for(a += sz, b += sz; a < b; a >>= 1, b >>= 1){ if(a & 1) l = f(l, seg[a++]); if(b & 1) r = f(seg[--b], r); } return f(l, r); } T operator[](const int &k) const{ return seg[k + sz]; } template int findSubtree(int a, const C &check, T &m, bool type){ while(a < sz){ T nxt = type ? f(seg[2 * a + type], m): f(m, seg[2 * a + type]); if(check(nxt)) a = 2 * a + type; else m = nxt, a = 2 * a + 1 - type; } return a - sz; } template int findFirst(int a, const C &check){ T l = e; if(a <= 0){ if(check(f(l, seg[1]))) return findSubtree(1, check, l, false); return -1; } int b = sz; for(a += sz, b += sz; a < b; a >>= 1, b >>= 1){ if(a & 1) { T nxt = f(l, seg[a]); if(check(nxt)) return findSubtree(a, check, l, false); l = nxt; ++a; } } return -1; } template int findLast(int b, const C &check){ T r = e; if(b >= sz) { if(check(f(seg[1], r))) return findSubtree(1, check, r, true); return -1; } int a = sz; for(b += sz; a < b; a >>= 1, b >>= 1){ if(b & 1){ T nxt = f(seg[--b], r); if(check(nxt)) return findSubtree(b, check, r, true); r = nxt; } } return -1; } }; #line 2 "data-structure/segment-tree/range-sum-query.hpp" struct RangeSumQuery{ int n; SegmentTree seg; RangeSumQuery(int n): n(n), seg(n, [&](short l, short r){ return l + r; }, 0){ } void update(int k, int val){ seg.update(k, val); } void add(int k, int val){ seg.update(k, seg.query(k, k+1) + val); } short query(int l, int r){ return seg.query(l, r); } }; #line 3 "main.cpp" template struct Compress{ vector xs; Compress() = default; Compress(const vector &vs){ add(vs); } Compress(const initializer_list> &vs) { for(auto &p :vs) add(p); } void add(const vector &vs) { copy(begin(vs), end(vs), back_inserter(xs)); } void add(const T &x) { xs.emplace_back(x); } void build() { sort(ALL(xs)); xs.erase(unique(ALL(xs)), end(xs)); } vector get(const vector &vs) const{ vector ret; transform(ALL(vs), back_inserter(ret), [&](const T &x) { return lower_bound(ALL(xs), x) - begin(xs); }); return ret; } int get(const T &x) const{ return lower_bound(ALL(xs), x) - begin(xs); } const T &operator[](int k) const { return xs[k]; } }; int main(){ int n; cin >> n; VI cmp; map xId; vector x(n); VI l(n), r(n); REP(i, n) { cin >> x[i] >> l[i] >> r[i]; cmp.PB(l[i]); cmp.PB(r[i]); } int q; cin >> q; vector> query(q); REP(i,q){ int t; cin >> t; pair item; item.second.PB(t); if(t == 1){ cin >> item.first; if(!xId.count(item.first)) xId[item.first] = xId.size(); int p; cin >> p; item.second.PB(p); cmp.PB(p); }else if(t == 2){ int p; cin >> p; item.second.PB(p); cmp.PB(p); }else{ cin >> item.first; int l, r; cin >> l >> r; item.second.PB(l); item.second.PB(r); cmp.PB(l); cmp.PB(r); } query[i] = item; } sort(ALL(cmp)); Compress comp(cmp); comp.build(); RangeSumQuery rsq(comp.xs.size()+1); vector vrsq(xId.size(), RangeSumQuery(comp.xs.size()+1)); REP(i,n){ rsq.add(comp.get(l[i]), 1); rsq.add(comp.get(r[i])+1, -1); if(xId.count(x[i])){ vrsq[xId[x[i]]].add(comp.get(l[i]), 1); vrsq[xId[x[i]]].add(comp.get(r[i])+1, -1); } } REP(i,q){ int t = query[i].second[0]; if(t == 1){ string xp = query[i].first; int p = query[i].second[1]; cout << (vrsq[xId[xp]].query(0, comp.get(p)+1) >= 1? "Yes" : "No") << endl; }else if(t == 2){ int p = query[i].second[1]; cout << rsq.query(0, comp.get(p)+1) << endl; }else{ string xp = query[i].first; int lp = query[i].second[1]; int rp = query[i].second[2]; rsq.add(comp.get(lp), 1); rsq.add(comp.get(rp)+1, -1); if(xId.count(xp)){ vrsq[xId[xp]].add(comp.get(lp), 1); vrsq[xId[xp]].add(comp.get(rp)+1, -1); } } } }