Problem p02904 (C++)

Buggy submission (status: Runtime Error):
/**
 * Created by hiramekun at 20:53 on 2019-09-21.
 */
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
using vb = vector<bool>;
using P = pair<ll, ll>;
template <typename T> using pq = priority_queue<T>;
template <typename T> using minpq = priority_queue<T, vector<T>, greater<T>>;
template <typename T, typename K> using ump = unordered_map<T, K>;
const ll dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const ll mod = 1000000007;
const ll inf = ll(1e9);
const ll e5 = ll(1e5);
const ll ll_inf = ll(1e9) * ll(1e9);

#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define repr(i, n) for (ll i = ll(n - 1); i >= 0; i--)
#define each(i, mp) for (auto &i : mp)
#define eb emplace_back
#define F first
#define S second
#define all(obj) (obj).begin(), (obj).end()

template <class T> ostream &operator<<(ostream &out, const vector<T> &list) {
  ll n = list.size();
  rep(i, n) out << list[i] << ' ';
  return out;
}

template <class T> istream &operator>>(istream &in, vector<T> &list) {
  ll n = list.size();
  rep(i, n) in >> list[i];
  return in;
}

template <class T>
ostream &operator<<(ostream &out, const vector<vector<T>> &list) {
  ll n = list.size();
  rep(i, n) out << list[i] << '\n';
  return out;
}

// sample: http://beet-aizu.hatenablog.com/entry/2017/12/01/225955
// verified with
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G
template <typename Data, typename Lazy> struct SegmentTree {
public:
  // mergeするときの操作
  using MergeData = function<Data(Data, Data)>;
  // lazyをxでupdate
  using UpdateLazyFromX = function<Lazy(Lazy, Lazy)>;
  // dataをlazyでupdate
  using UpdateDataFromLazy = function<Data(Data, Lazy)>;
  // lenが与えられた時にlazyを計算
  using CalcLazyWithLen = function<Lazy(Lazy, ll)>;

  // O(N)
  SegmentTree(int n, const MergeData fm, const UpdateLazyFromX fl,
              const UpdateDataFromLazy fa, const CalcLazyWithLen fw, Data M1,
              Lazy A1)
      : fm(fm), fl(fl), fa(fa), fw(fw), M1(M1), A1(A1) {
    sz = 1;
    while (sz < n)
      sz *= 2;
    seg.assign(2 * sz - 1, M1);
    //        lazy.assign(2 * sz - 1, A1);
  }

  void build(const vector<Data> &v) {
    rep(i, sz) seg[i + sz - 1] = v[i];
    for (ll i = sz - 2; i >= 0; --i) {
      seg[i] = fm(seg[i * 2 + 1], seg[i * 2 + 2]);
    }
  }

  //    // O(logN)
  //    Data update(int a, int b, Data x) {
  //        return update(a, b, x, 0, 0, sz);
  //    }

  // O(logN)
  Data query(int a, int b) { return query(a, b, 0, 0, sz); }

  int sz;
  vector<Data> seg;
  //    vector<Lazy> lazy;

private:
  const MergeData fm;
  const UpdateLazyFromX fl;
  const UpdateDataFromLazy fa;
  const CalcLazyWithLen fw;
  const Data M1;
  const Lazy A1;

  //    void eval(int len, int k) {
  //        if (lazy[k] == A1) return;
  //        if (k * 2 + 1 < sz * 2 - 1) {
  //            lazy[2 * k + 1] = fl(lazy[2 * k + 1], lazy[k]);
  //            lazy[2 * k + 2] = fl(lazy[2 * k + 2], lazy[k]);
  //        }
  //        seg[k] = fa(seg[k], fw(lazy[k], len));
  //        lazy[k] = A1;
  //    }

  //    Data update(int a, int b, Data x, int k, int l, int r) {
  ////        eval(r - l, k);
  //        if (r <= a || b <= l) return seg[k];
  //        if (a <= l && r <= b) {
  //            lazy[k] = fl(lazy[k], x);
  //            return fa(seg[k], fw(lazy[k], r - l));
  //        }
  //        return seg[k] = fm(update(a, b, x, k * 2 + 1, l, (l + r) / 2),
  //                           update(a, b, x, k * 2 + 2, (l + r) / 2, r));
  //    }

  Data query(int a, int b, int k, int l, int r) {
    //        eval(r - l, k);
    if (r <= a || b <= l)
      return M1;
    if (a <= l && r <= b)
      return seg[k];
    Data vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    Data vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return fm(vl, vr);
  }
};

/* ------------- ANSWER ------------- */
/* ---------------------------------- */

void solve() {
  ll n, k;
  cin >> n >> k;
  vl p(n);
  cin >> p;
  ll same = 0, cont = 0;
  rep(i, n) {
    ll c = 0;
    while (i + 1 < n && p[i] < p[i + 1]) {
      c++;
      i++;
    }
    ll tmp = max(0LL, (c - k + 2));
    same += tmp;
    cont += max(0LL, tmp - 1);
  }
  auto fm1 = [](ll a, ll b) { return min(a, b); };
  auto fl1 = [](ll a, ll b) { return min(a, b); };
  auto fa1 = [](ll a, ll b) { return min(a, b); };
  auto fw1 = [](ll a, ll w) { return a; };
  SegmentTree<ll, ll> minTree(n, fm1, fl1, fa1, fw1, INT_MAX, INT_MAX);
  auto fm2 = [](ll a, ll b) { return max(a, b); };
  auto fl2 = [](ll a, ll b) { return max(a, b); };
  auto fa2 = [](ll a, ll b) { return max(a, b); };
  auto fw2 = [](ll a, ll w) { return a; };
  SegmentTree<ll, ll> maxTree(n, fm2, fl2, fa2, fw2, INT_MIN, INT_MIN);
  minTree.build(p);
  maxTree.build(p);

  ll prev_min = ll_inf, prev_max = ll_inf;
  ll ans = 0;
  rep(i, n - k + 1) {
    ll mi = minTree.query(i, i + k);
    ll mx = maxTree.query(i, i + k);
    if ((prev_min < mi && prev_max < mx))
      ;
    else
      ans++;
    prev_min = mi, prev_max = mx;
  }
  if (same > 0) {
    ans -= (same - cont);
    ans++;
  }
  cout << max(1LL, ans) << '\n';
}

int main() {
#ifdef MY_DEBUG
  while (true) {
#endif
    solve();
#ifdef MY_DEBUG
  }
#endif
  return 0;
}

Fixed submission:
/**
 * Created by hiramekun at 20:53 on 2019-09-21.
 */
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using vl = vector<ll>;
using vvl = vector<vl>;
using vb = vector<bool>;
using P = pair<ll, ll>;
template <typename T> using pq = priority_queue<T>;
template <typename T> using minpq = priority_queue<T, vector<T>, greater<T>>;
template <typename T, typename K> using ump = unordered_map<T, K>;
const ll dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
const ll mod = 1000000007;
const ll inf = ll(1e9);
const ll e5 = ll(1e5);
const ll ll_inf = ll(1e9) * ll(1e9);

#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define repr(i, n) for (ll i = ll(n - 1); i >= 0; i--)
#define each(i, mp) for (auto &i : mp)
#define eb emplace_back
#define F first
#define S second
#define all(obj) (obj).begin(), (obj).end()

template <class T> ostream &operator<<(ostream &out, const vector<T> &list) {
  ll n = list.size();
  rep(i, n) out << list[i] << ' ';
  return out;
}

template <class T> istream &operator>>(istream &in, vector<T> &list) {
  ll n = list.size();
  rep(i, n) in >> list[i];
  return in;
}

template <class T>
ostream &operator<<(ostream &out, const vector<vector<T>> &list) {
  ll n = list.size();
  rep(i, n) out << list[i] << '\n';
  return out;
}

// sample: http://beet-aizu.hatenablog.com/entry/2017/12/01/225955
// verified with
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_A
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_F
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_G
template <typename Data, typename Lazy> struct SegmentTree {
public:
  // mergeするときの操作
  using MergeData = function<Data(Data, Data)>;
  // lazyをxでupdate
  using UpdateLazyFromX = function<Lazy(Lazy, Lazy)>;
  // dataをlazyでupdate
  using UpdateDataFromLazy = function<Data(Data, Lazy)>;
  // lenが与えられた時にlazyを計算
  using CalcLazyWithLen = function<Lazy(Lazy, ll)>;

  // O(N)
  SegmentTree(int n, const MergeData fm, const UpdateLazyFromX fl,
              const UpdateDataFromLazy fa, const CalcLazyWithLen fw, Data M1,
              Lazy A1)
      : fm(fm), fl(fl), fa(fa), fw(fw), M1(M1), A1(A1) {
    sz = 1;
    while (sz < n)
      sz *= 2;
    seg.assign(2 * sz - 1, M1);
    //        lazy.assign(2 * sz - 1, A1);
  }

  void build(const vector<Data> &v) {
    ll n = v.size();
    rep(i, n) seg[i + sz - 1] = v[i];
    for (ll i = sz - 2; i >= 0; --i) {
      seg[i] = fm(seg[i * 2 + 1], seg[i * 2 + 2]);
    }
  }

  //    // O(logN)
  //    Data update(int a, int b, Data x) {
  //        return update(a, b, x, 0, 0, sz);
  //    }

  // O(logN)
  Data query(int a, int b) { return query(a, b, 0, 0, sz); }

  int sz;
  vector<Data> seg;
  //    vector<Lazy> lazy;

private:
  const MergeData fm;
  const UpdateLazyFromX fl;
  const UpdateDataFromLazy fa;
  const CalcLazyWithLen fw;
  const Data M1;
  const Lazy A1;

  //    void eval(int len, int k) {
  //        if (lazy[k] == A1) return;
  //        if (k * 2 + 1 < sz * 2 - 1) {
  //            lazy[2 * k + 1] = fl(lazy[2 * k + 1], lazy[k]);
  //            lazy[2 * k + 2] = fl(lazy[2 * k + 2], lazy[k]);
  //        }
  //        seg[k] = fa(seg[k], fw(lazy[k], len));
  //        lazy[k] = A1;
  //    }

  //    Data update(int a, int b, Data x, int k, int l, int r) {
  ////        eval(r - l, k);
  //        if (r <= a || b <= l) return seg[k];
  //        if (a <= l && r <= b) {
  //            lazy[k] = fl(lazy[k], x);
  //            return fa(seg[k], fw(lazy[k], r - l));
  //        }
  //        return seg[k] = fm(update(a, b, x, k * 2 + 1, l, (l + r) / 2),
  //                           update(a, b, x, k * 2 + 2, (l + r) / 2, r));
  //    }

  Data query(int a, int b, int k, int l, int r) {
    //        eval(r - l, k);
    if (r <= a || b <= l)
      return M1;
    if (a <= l && r <= b)
      return seg[k];
    Data vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
    Data vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
    return fm(vl, vr);
  }
};

/* ------------- ANSWER ------------- */
/* ---------------------------------- */

void solve() {
  ll n, k;
  cin >> n >> k;
  vl p(n);
  cin >> p;
  ll same = 0, cont = 0;
  rep(i, n) {
    ll c = 0;
    while (i + 1 < n && p[i] < p[i + 1]) {
      c++;
      i++;
    }
    ll tmp = max(0LL, (c - k + 2));
    same += tmp;
    cont += max(0LL, tmp - 1);
  }
  auto fm1 = [](ll a, ll b) { return min(a, b); };
  auto fl1 = [](ll a, ll b) { return min(a, b); };
  auto fa1 = [](ll a, ll b) { return min(a, b); };
  auto fw1 = [](ll a, ll w) { return a; };
  SegmentTree<ll, ll> minTree(n, fm1, fl1, fa1, fw1, INT_MAX, INT_MAX);
  auto fm2 = [](ll a, ll b) { return max(a, b); };
  auto fl2 = [](ll a, ll b) { return max(a, b); };
  auto fa2 = [](ll a, ll b) { return max(a, b); };
  auto fw2 = [](ll a, ll w) { return a; };
  SegmentTree<ll, ll> maxTree(n, fm2, fl2, fa2, fw2, INT_MIN, INT_MIN);
  minTree.build(p);
  maxTree.build(p);

  ll prev_min = ll_inf, prev_max = ll_inf;
  ll ans = 0;
  rep(i, n - k + 1) {
    ll mi = minTree.query(i, i + k);
    ll mx = maxTree.query(i, i + k);
    if ((prev_min < mi && prev_max < mx))
      ;
    else
      ans++;
    prev_min = mi, prev_max = mx;
  }
  if (same > 0) {
    ans -= (same - cont);
    ans++;
  }
  cout << max(1LL, ans) << '\n';
}

int main() {
#ifdef MY_DEBUG
  while (true) {
#endif
    solve();
#ifdef MY_DEBUG
  }
#endif
  return 0;
}