Problem p02904 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// #include <boost/multiprecision/cpp_int.hpp>
// typedef boost::multiprecision::cpp_int ll;
typedef long double dd;
#define i_7 (ll)(1E9 + 7)
// #define i_7 998244353
#define i_5 i_7 - 2
ll mod(ll a) {
  ll c = a % i_7;
  if (c >= 0)
    return c;
  return c + i_7;
}
typedef pair<ll, ll> l_l;
ll inf = (ll)1E17;
#define rep(i, l, r) for (ll i = l; i <= r; i++)
#define pb push_back
ll max(ll a, ll b) {
  if (a < b)
    return b;
  else
    return a;
}
ll min(ll a, ll b) {
  if (a > b)
    return b;
  else
    return a;
}
void Max(ll &pos, ll val) { pos = max(pos, val); } // Max(dp[n],dp[n-1]);
void Min(ll &pos, ll val) { pos = min(pos, val); }
void Add(ll &pos, ll val) { pos = mod(pos + val); }
dd EPS = 1E-9;
#define fastio                                                                 \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(0);                                                                  \
  cout.tie(0);
///////////////////////////////////////
// 区間最大区間加算
struct RBQRAQ {
  ll n;
  vector<ll> data, lazy;
  RBQRAQ(ll vs) {
    n = 1;
    while (n < vs)
      n *= 2;
    data.resize(2 * n - 1, 0);
    lazy.resize(2 * n - 1, 0);
  }
  void eval(ll k, ll l, ll r) {
    if (lazy[k] != 0) {
      data[k] += lazy[k];
      if (r - l > 1) {
        lazy[2 * k + 1] += lazy[k];
        lazy[2 * k + 2] += lazy[k];
      }
      lazy[k] = 0;
    }
  }
  void add(ll a, ll b, ll x, ll k, ll l, ll r) {
    eval(k, l, r);
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      lazy[k] += x;
      eval(k, l, r);
    } else {
      add(a, b, x, 2 * k + 1, l, (l + r) / 2);
      add(a, b, x, 2 * k + 2, (l + r) / 2, r);
      data[k] = max(data[2 * k + 1], data[2 * k + 2]);
    }
  }
  void add(ll a, ll b, ll x) { add(a, b, x, 0, 0, n); } //[a,b)にxを加える
  ll query(ll a, ll b, ll k, ll l, ll r) {
    eval(k, l, r);
    if (r <= a || b <= l)
      return -inf;
    if (a <= l && r <= b) {
      return data[k];
    } else {
      ll vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
      ll vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
      return max(vl, vr);
    }
  }
  ll query(ll a, ll b) { return query(a, b, 0, 0, n); } //[a,b)の最大値
};
//////////////////////////////////////////////////////

const ll MAX_N = 1 << 20;
// セグメント木を持つグローバル配列
ll n, dat[2 * MAX_N - 1];
// 初期化
void init(ll n_) {
  // 簡単のため要素数を2のべき乗に
  n = 1;
  while (n < n_)
    n *= 2;
  // 全ての値をinfに
  for (ll i = 0; i < 2 * n - 1; i++)
    dat[i] = inf;
}
// k番目の値(0-indexed)をaに変更
void update(ll k, ll a) {
  // 葉の節点
  k += n - 1;
  dat[k] = a;
  // 登りながら更新
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
}
//[a,b)の最小値を求める
// 後ろの方の引数は、計算の簡単のための引数
// kは節点の番号、l,rはその節点が[l,r)に対応づいていることを表す。
ll query(ll a, ll b, ll k, ll l, ll r) {
  //[a,b)と[l,r)が交差しなければinf
  if (r <= a || b <= l)
    return inf;
  //[a,b)が[l,r)を完全に含んでいれば、この節点の値
  if (a <= l && r <= b)
    return dat[k];
  else {
    // そうでなければ、2つの子の最小値
    ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
}
//[a,b)の最小値
ll que(ll a, ll b) { return query(a, b, 0, 0, n); }
/////////////////////////////////////////////////////

int main() {
  fastio ll n, k;
  cin >> n >> k;
  ll p[n];
  rep(i, 0, n - 1) cin >> p[i];
  RBQRAQ u(n);

  init(n);
  rep(i, 0, n - 1) { update(i, p[i]); }

  rep(i, 0, n - 1) { u.add(i, i + 1, p[i]); }
  vector<ll> v;
  ll pos = n - 1;
  ll cou = 1;
  ll res[10];
  res[n - 1] = 1;
  while (pos >= 0) {
    while (pos - 1 >= 0) {
      if (p[pos - 1] < p[pos]) {
        cou++;
        pos--;
        res[pos] = cou;
      } else {
        cou = 1;
        break;
      }
    }
    pos--;
    res[pos] = cou;
    cou = 1;
  }
  /*rep(i,0,n-1){
      cout<<res[i]<<" ";
  }cout<<endl;
  */

  ll count = 0;
  rep(i, 0, n - 1) {
    if (res[i] >= k)
      count++;
  }

  ll ans = n - k + 1 - max(0, count - 1);
  rep(i, 0, n - k - 1) {
    // cout<<endl<<i<<" ";
    if (res[i] >= k)
      continue;
    ll c = u.query(i + 1, i + k);
    ll a = u.query(i, i + 1);
    ll b = u.query(i + k, i + k + 1);
    ll d = que(i + 1, i + k);
    if (a < d && c < b)
      ans--;
    // cout<<a<<" "<<d<<" "<<c<<" "<<b;
  }
  // cout<<endl;

  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// #include <boost/multiprecision/cpp_int.hpp>
// typedef boost::multiprecision::cpp_int ll;
typedef long double dd;
#define i_7 (ll)(1E9 + 7)
// #define i_7 998244353
#define i_5 i_7 - 2
ll mod(ll a) {
  ll c = a % i_7;
  if (c >= 0)
    return c;
  return c + i_7;
}
typedef pair<ll, ll> l_l;
ll inf = (ll)1E17;
#define rep(i, l, r) for (ll i = l; i <= r; i++)
#define pb push_back
ll max(ll a, ll b) {
  if (a < b)
    return b;
  else
    return a;
}
ll min(ll a, ll b) {
  if (a > b)
    return b;
  else
    return a;
}
void Max(ll &pos, ll val) { pos = max(pos, val); } // Max(dp[n],dp[n-1]);
void Min(ll &pos, ll val) { pos = min(pos, val); }
void Add(ll &pos, ll val) { pos = mod(pos + val); }
dd EPS = 1E-9;
#define fastio                                                                 \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(0);                                                                  \
  cout.tie(0);
///////////////////////////////////////
// 区間最大区間加算
struct RBQRAQ {
  ll n;
  vector<ll> data, lazy;
  RBQRAQ(ll vs) {
    n = 1;
    while (n < vs)
      n *= 2;
    data.resize(2 * n - 1, 0);
    lazy.resize(2 * n - 1, 0);
  }
  void eval(ll k, ll l, ll r) {
    if (lazy[k] != 0) {
      data[k] += lazy[k];
      if (r - l > 1) {
        lazy[2 * k + 1] += lazy[k];
        lazy[2 * k + 2] += lazy[k];
      }
      lazy[k] = 0;
    }
  }
  void add(ll a, ll b, ll x, ll k, ll l, ll r) {
    eval(k, l, r);
    if (r <= a || b <= l)
      return;
    if (a <= l && r <= b) {
      lazy[k] += x;
      eval(k, l, r);
    } else {
      add(a, b, x, 2 * k + 1, l, (l + r) / 2);
      add(a, b, x, 2 * k + 2, (l + r) / 2, r);
      data[k] = max(data[2 * k + 1], data[2 * k + 2]);
    }
  }
  void add(ll a, ll b, ll x) { add(a, b, x, 0, 0, n); } //[a,b)にxを加える
  ll query(ll a, ll b, ll k, ll l, ll r) {
    eval(k, l, r);
    if (r <= a || b <= l)
      return -inf;
    if (a <= l && r <= b) {
      return data[k];
    } else {
      ll vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
      ll vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
      return max(vl, vr);
    }
  }
  ll query(ll a, ll b) { return query(a, b, 0, 0, n); } //[a,b)の最大値
};
//////////////////////////////////////////////////////

const ll MAX_N = 1 << 20;
// セグメント木を持つグローバル配列
ll n, dat[2 * MAX_N - 1];
// 初期化
void init(ll n_) {
  // 簡単のため要素数を2のべき乗に
  n = 1;
  while (n < n_)
    n *= 2;
  // 全ての値をinfに
  for (ll i = 0; i < 2 * n - 1; i++)
    dat[i] = inf;
}
// k番目の値(0-indexed)をaに変更
void update(ll k, ll a) {
  // 葉の節点
  k += n - 1;
  dat[k] = a;
  // 登りながら更新
  while (k > 0) {
    k = (k - 1) / 2;
    dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
  }
}
//[a,b)の最小値を求める
// 後ろの方の引数は、計算の簡単のための引数
// kは節点の番号、l,rはその節点が[l,r)に対応づいていることを表す。
ll query(ll a, ll b, ll k, ll l, ll r) {
  //[a,b)と[l,r)が交差しなければinf
  if (r <= a || b <= l)
    return inf;
  //[a,b)が[l,r)を完全に含んでいれば、この節点の値
  if (a <= l && r <= b)
    return dat[k];
  else {
    // そうでなければ、2つの子の最小値
    ll vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    ll vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
}
//[a,b)の最小値
ll que(ll a, ll b) { return query(a, b, 0, 0, n); }
/////////////////////////////////////////////////////

int main() {
  fastio ll n, k;
  cin >> n >> k;
  ll p[n];
  rep(i, 0, n - 1) cin >> p[i];
  RBQRAQ u(n);

  init(n);
  rep(i, 0, n - 1) { update(i, p[i]); }

  rep(i, 0, n - 1) { u.add(i, i + 1, p[i]); }
  vector<ll> v;
  ll pos = n - 1;
  ll cou = 1;
  ll res[n];
  res[n - 1] = 1;
  while (pos >= 0) {
    while (pos - 1 >= 0) {
      if (p[pos - 1] < p[pos]) {
        cou++;
        pos--;
        res[pos] = cou;
      } else {
        cou = 1;
        break;
      }
    }
    pos--;
    res[pos] = cou;
    cou = 1;
  }
  /*rep(i,0,n-1){
      cout<<res[i]<<" ";
  }cout<<endl;
  */

  ll count = 0;
  rep(i, 0, n - 1) {
    if (res[i] >= k)
      count++;
  }

  ll ans = n - k + 1 - max(0, count - 1);
  rep(i, 0, n - k - 1) {
    // cout<<endl<<i<<" ";
    if (res[i] >= k)
      continue;
    ll c = u.query(i + 1, i + k);
    ll a = u.query(i, i + 1);
    ll b = u.query(i + k, i + k + 1);
    ll d = que(i + 1, i + k);
    if (a < d && c < b)
      ans--;
    // cout<<a<<" "<<d<<" "<<c<<" "<<b;
  }
  // cout<<endl;

  cout << ans << endl;

  return 0;
}