Submission #1207646

#TimeUsernameProblemLanguageResultExecution timeMemory
1207646abczzFish 2 (JOI22_fish2)C++20
100 / 100
3913 ms199144 KiB
#include <iostream>
#include <map>
#include <array>
#include <algorithm>
#include <cmath>
#define ll long long

using namespace std;

ll n, q, ty, x, y, A[100000], X[100000], ps[100000];
ll listnx[100000][30], listpv[100000][30];
vector <ll> V[30];
struct BIT{
  ll bt[100001];
  void add(ll id, ll w) {
    ++id;
    while (id <= n) {
      bt[id] += w;
      id += id & -id;
    }
  }
  ll ask(ll id) {
    ll res = 0;
    while (id) {
      res += bt[id];
      id -= id & -id;
    }
    return res;
  }
  ll query(ll l, ll r) {
    if (l > r) return (ll)1e18;
    return ask(r+1) - ask(l);
  }
}bit;
array<ll, 2> operator+(array<ll, 2> a, array<ll, 2> b) {
  return {a[0] + b[0], a[1] + b[1]};
}
struct SegTree{
  array<ll, 2> st[400000];
  void update(ll id, ll l, ll r, ll q, array<ll, 2> w) {
    if (l == r) {
      st[id] = w;
      return;
    }
    ll mid = (l+r)/2;
    if (q <= mid) update(id*2, l, mid, q, w);
    else update(id*2+1, mid+1, r, q, w);
    st[id] = st[id*2] + st[id*2+1];
  }
  array<ll, 2> query(ll id, ll l, ll r, ll ql, ll qr) {
    if (qr < l || r < ql) return {0, 0};
    else if (ql <= l && r <= qr) return st[id];
    ll mid = (l+r)/2;
    return query(id*2, l, mid, ql, qr) + query(id*2+1, mid+1, r, ql, qr);
  }
}ST[30];
struct MapSegTree{
  ll st[400000];
  void build(ll id, ll l, ll r) {
    if (l == r) {
      st[id] = A[l];
      return;
    }
    ll mid = (l+r)/2;
    build(id*2, l, mid);
    build(id*2+1, mid+1, r);
    st[id] = max(st[id*2], st[id*2+1]);
  }
  void update(ll id, ll l, ll r, ll q, ll w) {
    if (l == r) {
      st[id] = w;
      return;
    }
    ll mid = (l+r)/2;
    if (q <= mid) update(id*2, l, mid, q, w);
    else update(id*2+1, mid+1, r, q, w);
    st[id] = max(st[id*2], st[id*2+1]);
  }
  ll queryL(ll id, ll l, ll r, ll ql, ll qr, ll w) {
    if (qr < l || r < ql || st[id] < w) return -1;
    else if (ql <= l && r <= qr) {
      if (l == r) return l;
      ll mid = (l+r)/2;
      if (st[id*2] >= w) return queryL(id*2, l, mid, ql, qr, w);
      else return queryL(id*2+1, mid+1, r, ql, qr, w);
    }
    ll mid = (l+r)/2, res = queryL(id*2, l, mid, ql, qr, w);
    return (res == -1 ? queryL(id*2+1, mid+1, r, ql, qr, w) : res);
  }
  ll queryR(ll id, ll l, ll r, ll ql, ll qr, ll w) {
    if (qr < l || r < ql || st[id] < w) return -1;
    else if (ql <= l && r <= qr) {
      if (l == r) return l;
      ll mid = (l+r)/2;
      if (st[id*2+1] >= w) return queryR(id*2+1, mid+1, r, ql, qr, w);
      else return queryR(id*2, l, mid, ql, qr, w);
    }
    ll mid = (l+r)/2, res = queryR(id*2+1, mid+1, r, ql, qr, w);
    return (res == -1 ? queryR(id*2, l, mid, ql, qr, w) : res);
  }
}ST2;

ll check(ll j, ll u, ll xl, ll xr) {
  ll ql = u, qr = u, v = 1e18;
  if (listpv[u][j] != -1) {
    ll pv = listpv[u][j];
    ql = pv+1;
    if (pv >= xl) v = min(v, A[pv]);
  }
  else ql = 0;
  ll nx = listnx[u][j];
  if (nx != -1) {
    qr = nx-1;
    if (nx <= xr) v = min(v, A[nx]);
  }
  else qr = n-1;
  ql = max(ql, xl);
  qr = min(qr, xr);
  if (bit.query(ql, qr) < v && v != 1e18) return 1;
  else return 0;
}
void reconstruct(ll j, ll l, ll r) {
  ll ql = l, qr = r-1, v = A[r], tot = 0;
  if (j == X[l]-1) tot = check(j, l, (ll)-1e18, (ll)1e18);
  array <ll, 2> u = {0, 0};
  if (j) u = ST[j-1].query(1, 0, n-1, l, r-1);
  if (bit.query(l+1, r-1) < min(A[l], A[r])) {
    ST[j].update(1, 0, n-1, l, {r-l-1-u[1]+tot, r-l-1+tot});
  }
  else {
    ST[j].update(1, 0, n-1, l, {tot, u[1]+tot});
  }
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cin >> n;
  for (int i=0; i<n; ++i) {
    cin >> A[i];
    bit.add(i, A[i]);
    ps[i] = A[i] + (i == 0 ? 0 : ps[i-1]);
    X[i] = (ll)(log2(A[i]));
    for (int j=0; j<X[i]; ++j) V[j].push_back(i);
    for (int j=0; j<30; ++j) listnx[i][j] = listpv[i][j] = -1;
  }
  for (int j=0; j<30; ++j) {
    for (int i=0; i+1<V[j].size(); ++i) {
      listnx[V[j][i]][j] = V[j][i+1];
      listpv[V[j][i+1]][j] = V[j][i];
      reconstruct(j, V[j][i], V[j][i+1]);
    }
  }
  ST2.build(1, 0, n-1);
  cin >> q;
  while (q--) {
    cin >> ty >> x >> y;
    if (ty == 1) {
      --x;
      ll z1 = X[x], z2 = (ll)log2(y);
      ST2.update(1, 0, n-1, x, y);
      bit.add(x, y-A[x]);
      A[x] = y, X[x] = z2;
      for (int j=0; j<30; ++j) {
        ST[j].update(1, 0, n-1, x, {0, 0});
        ll it = ST2.queryL(1, 0, n-1, x, n-1, (1<<(j+1)));
        listnx[x][j] = listpv[x][j] = -1;
        if (it != -1) {
          ll pv = ST2.queryR(1, 0, n-1, 0, it-1, (1<<(j+1)));
          if (pv != -1) {
            listnx[pv][j] = it;
            listpv[it][j] = pv;
            reconstruct(j, pv, it);
          }
          else listpv[it][j] = -1;
          if (it == x) {
            ll nx = ST2.queryL(1, 0, n-1, it+1, n-1, (1<<(j+1)));
            if (nx != -1) {
              listnx[it][j] = nx;
              listpv[nx][j] = it;
              reconstruct(j, it, nx);
              if (X[nx]-1 == j) {
                ll nx2 = ST2.queryL(1, 0, n-1, nx+1, n-1, (1<<(j+1)));
                if (nx2 != -1) reconstruct(j, nx, nx2);
              }
            }
            else listnx[it][j] = -1;
          }
          else if (X[it]-1 == j) {
            ll nx2 = ST2.queryL(1, 0, n-1, it+1, n-1, (1<<(j+1)));
            if (nx2 != -1) reconstruct(j, it, nx2);
          }
        }
        else {
          ll pv = ST2.queryR(1, 0, n-1, 0, x-1, (1<<(j+1)));
          if (pv != -1) {
            listnx[pv][j] = -1;
            ST[j].update(1, 0, n-1, pv, {0, 0});
          }
        }
      }
    }
    else {
      --x, --y;
      ll f = y-x+1, nx = x, ny = y;
      for (int j=0; j<30; ++j) {
        ll it = ST2.queryL(1, 0, n-1, x, n-1, (1LL<<(j+1)));
        if (it == -1 || it > y) continue;
        ll it2 = ST2.queryR(1, 0, n-1, 0, y, (1LL<<(j+1)));
        if (bit.query(x, it-1) < A[it]) nx = it;
        if (bit.query(it2+1, y) < A[it2]) ny = it2;
      }
      f -= nx-x+y-ny;
      for (int j=0; j<30; ++j) {
        ll it = ST2.queryL(1, 0, n-1, nx, n-1, (1<<(j+1)));
        if (it == -1 || it > ny) continue;
        ll it2 = ST2.queryR(1, 0, n-1, 0, ny, (1<<(j+1)));
        if (it != it2) {
          auto u = ST[j].query(1, 0, n-1, it, it2-1);
          if (X[it]-1 == j) u[0] += check(j, it, x, y) - check(j, it, (ll)-1e18, (ll)1e18);
          f -= u[0];
        }
        if (X[it2]-1 == j) {
          f -= check(j, it2, x, y);
        }
      }
      cout << f << '\n';
    }
  }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...