//#pragma GCC optimize("O3") //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx") #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef LOCAL #define eprintf(...) fprintf(stderr,__VA_ARGS__) clock_t __my_start_clock = clock(); #else #define eprintf(...) #endif #define TIMESTAMP(x) eprintf("["#x"] Time : %.3lf s.\n", (clock() - __my_start_clock)*1.0/CLOCKS_PER_SEC) #define TIMESTAMPf(x,...) eprintf("[" x "] Time : %.3lf s.\n", __VA_ARGS__, (clock() - __my_start_clock)*1.0/CLOCKS_PER_SEC) #define db(x) cerr << #x << " = " << x << endl #define db2(x, y) cerr << "(" << #x << ", " << #y << ") = (" << x << ", " << y << ")\n"; #define db3(x, y, z) cerr << "(" << #x << ", " << #y << ", " << #z << ") = (" << x << ", " << y << ", " << z << ")\n" #define dbv(a) cerr << #a << " = "; for (auto xxxx: a) cerr << xxxx << " "; cerr << endl using namespace std; #ifdef LOCAL static struct __timestamper { string what; __timestamper(const char* what) : what(what){}; __timestamper(const string& what) : what(what){}; ~__timestamper(){ TIMESTAMPf("%s", what.data()); } } __TIMESTAMPER("end"); #else struct __timestamper {}; #endif using ll = long long; struct query { int type; int l, r; int delta; }; const string YES = "YES"; const string NO = "NO"; const ll FAKE = 8e18; struct segtree { struct item { int len; ll left, right; ll left2, right2; ll leftmin, rightmin; bool ok; item() { len = 0; } item(ll x) { len = 1; left = right = x; left2 = right2 = FAKE; leftmin = rightmin = FAKE; ok = true; } item(const item &x, const item &y) { *this = combine(x, y); } item combine(const item &x, const item &y) { if (x.len == 0) return y; if (y.len == 0) return x; item res; res.len = x.len + y.len; res.left = x.left; res.right = y.right; res.left2 = x.left2 == FAKE ? (x.left == y.left ? y.left2 : y.left) : x.left2; res.right2 = y.right2 == FAKE ? (x.right == y.right ? x.right2 : x.right) : y.right2; res.ok = x.ok && y.ok && (x.rightmin == FAKE || y.leftmin == FAKE || x.rightmin < y.leftmin); res.leftmin = x.leftmin == FAKE ? y.leftmin : x.leftmin; res.rightmin = y.rightmin == FAKE ? x.rightmin : y.rightmin; ll mid = min(x.right, y.left); ll neqR = y.left == mid ? y.left2 : y.left; ll neqL = x.right == mid ? x.right2 : x.right; if (neqL != FAKE && neqR != FAKE && mid < neqL && mid < neqR) { res.ok &= (x.rightmin == FAKE || x.rightmin < mid) && (y.leftmin == FAKE || mid < y.leftmin); if (x.leftmin == FAKE) res.leftmin = mid; if (y.rightmin == FAKE) res.rightmin = mid; } return res; } void add(ll delta) { left += delta; right += delta; if (left2 != FAKE) left2 += delta; if (right2 != FAKE) right2 += delta; if (leftmin != FAKE) leftmin += delta; if (rightmin != FAKE) rightmin += delta; } bool check() const { if (left2 == FAKE) return true; bool is_left_min = left2 > left; bool is_right_min = right2 > right; bool res = ok; res &= !is_left_min || leftmin == FAKE || left < leftmin; res &= !is_right_min || rightmin == FAKE || rightmin < right; res &= !is_left_min || !is_right_min || left < right; return res; } }; int n; vector t; vector p; segtree(vector _a) { n = _a.size(); t.resize(4 * n); p.assign(4 * n, 0); build(_a, 1, 0, n - 1); } void build(const vector &a, int v, int tl, int tr) { if (tl == tr) { t[v] = item(a[tl]); return; } int tm = (tl + tr) >> 1; build(a, v * 2, tl, tm); build(a, v * 2 + 1, tm + 1, tr); t[v] = item(t[v * 2], t[v * 2 + 1]); } void push(int v, int tl, int tr) { t[v].add(p[v]); if (tl != tr) { p[v * 2] += p[v]; p[v * 2 + 1] += p[v]; } p[v] = 0; } void add(int l, int r, int delta) { add(1, 0, n - 1, l, r, delta); } void add(int v, int tl, int tr, int l, int r, ll delta) { push(v, tl, tr); if (l > r) return; if (l == tl && r == tr) { p[v] += delta; push(v, tl, tr); return; } int tm = (tl + tr) >> 1; add(v * 2, tl, tm, l, min(r, tm), delta); add(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r, delta); t[v] = item(t[v * 2], t[v * 2 + 1]); } item get(int l, int r) { return get(1, 0, n - 1, l, r); } item get(int v, int tl, int tr, int l, int r) { push(v, tl, tr); if (l > r) return item(); if (l == tl && r == tr) return t[v]; int tm = (tl + tr) >> 1; return item( get(v * 2, tl, tm, l, min(r, tm)), get(v * 2 + 1, tm + 1, tr, max(l, tm + 1), r) ); } }; vector solve(vector a, vector b) { segtree tr(a); vector res; for (auto q : b) { if (q.type == 0) { tr.add(q.l, q.r, q.delta); } else { res.push_back(tr.get(q.l, q.r).check() ? YES : NO); } } return res; } vector slow(vector a, vector b) { vector res; for (auto q : b) { if (q.type == 0) { for (int i = q.l; i <= q.r; i++) { a[i] += q.delta; } } else { auto c = vector(a.begin() + q.l, a.begin() + q.r + 1); c.resize(std::unique(c.begin(), c.end()) - c.begin()); ll locmin = std::numeric_limits::min(); bool ok = 1; for (int i = 0; i < (int)c.size(); i++) { if ((i == 0 || c[i] < c[i - 1]) && (i + 1 == c.size() || c[i] < c[i + 1])) { ok &= locmin < c[i]; locmin = c[i]; } } res.push_back(ok ? YES : NO); } } return res; } void stress() { for (int it = 0;; it++) { if (it % 100 == 0) db(it); mt19937 rnd(it); int N = 1000; int n = rnd() % N + 1; int q = rnd() % N + 1; const int C = N; vector a(n); for (ll &x : a) x = rnd() % (2 * C + 1); vector b(q); for (int i = 0; i < q; i++) { b[i].type = rnd() % 1; b[i].l = rnd() % n; b[i].r = rnd() % n; if (b[i].l > b[i].r) swap(b[i].l, b[i].r); b[i].delta = rnd() % (2 * C + 1) - C; } auto ans1 = solve(a, b); auto ans2 = slow(a, b); if (ans1 != ans2) { cout << "it: " << it << endl; cout << n << " " << q << endl; for (auto x : a) cout << x << " "; cout << endl; for (auto x : b) cout << x.type << " " << x.l << " " << x.r << " " << x.delta << endl; cout << "===" << endl; for (auto s : ans1) cout << s << endl; cout << "=== instead of ===" << endl; for (auto s : ans2) cout << s << endl; exit(0); } } } int main() { #ifdef LOCAL freopen("in", "r", stdin); #endif // stress(); int n; scanf("%d", &n); vector a(n); for (ll &x : a) scanf("%lld", &x); int q; scanf("%d", &q); vector b(q); for (auto &x : b) { static char buf[100]; scanf("%s", buf); if ((string)buf == "update") { x.type = 0; scanf("%d%d%d", &x.l, &x.r, &x.delta); } else if ((string)buf == "check") { x.type = 1; scanf("%d%d", &x.l, &x.r); } else assert(0); x.l--; x.r--; } auto ans = solve(a, b); for (auto s : ans) printf("%s\n", s.c_str()); return 0; }