Problem p02575 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
typedef pair<long, long> P;
int main() {
  long H, W;
  cin >> H >> W;
  set<P> S, T;
  for (long i = 0; i < W; i++) {
    S.insert(P(i, 0));
    T.insert(P(0, i));
  }
  for (long k = 0; k < H; k++) {
    long a, b;
    cin >> a >> b;
    a--;
    long y = LONG_MAX;
    for (auto itr = S.lower_bound(P(a, -1));
         itr != S.end() && (itr->first) < b;) {
      P x = *itr;
      y = min(y, x.second + b - x.first);
      T.erase(P(x.second, x.first));
      itr = S.erase(itr);
    } // ゴール: 移動回数 i,jとして, b, j+b-i, このうち,
      // 最も移動回数が少ないものだけ残す
    if (y != LONG_MAX && b < W) {
      S.insert(P(b, y));
      T.insert(P(y, b));
    }
    cout << (T.size() ? (T.begin()->first) + k + 1 : -1) << endl;
  }
}

/*

S: ゴール, 何回の移動でいけるか
T: 何回の移動でいけるか, ゴール

T.begin()を持って来ればいける
Sで更新を素早くみる





*/

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
long inf = INT_MAX;
struct LazySegmentTree {
private:
  int n;
  vector<ll> node, lazy;

public:
  LazySegmentTree(vector<ll> v) {
    int sz = (int)v.size();
    n = 1;
    while (n < sz)
      n *= 2;
    node.resize(2 * n - 1);
    lazy.resize(2 * n - 1, -1);

    for (int i = 0; i < sz; i++)
      node[i + n - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = min(node[i * 2 + 1], node[i * 2 + 2]);
  }

  // k 番目のノードについて遅延評価を行う
  void eval(int k, int l, int r) {

    // 遅延配列が空でない場合、自ノード及び子ノードへの
    // 値の伝播が起こる
    if (lazy[k] != -1) {
      // if(r - l > 1) {eval(2*k+1,l,(l+r)/2);eval(2*k+2,(l+r)/2,r);}// ??
      // 先に下を解決しておく
      node[k] = max(node[k], lazy[k]);

      // 最下段かどうかのチェックをしよう
      // 子ノードは親ノードの 1/2 の範囲であるため、
      // 伝播させるときは半分にする
      if (r - l > 1) {
        // lazy[2*k+1] = lazy[k];
        // lazy[2*k+2] = lazy[k]+(r-l)/2;
        lazy[2 * k + 1] = max(lazy[2 * k + 1], lazy[k]);
        lazy[2 * k + 2] = max(lazy[2 * k + 2], lazy[k] + (r - l) / 2);
      }

      // 伝播が終わったので、自ノードの遅延配列を空にする
      lazy[k] = -1;
    }
  }
  void add(int a, int b, ll x, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;

    // k 番目のノードに対して遅延評価を行う
    eval(k, l, r);

    // 範囲外なら何もしない
    if (b <= l || r <= a)
      return;

    // 完全に被覆しているならば、遅延配列に値を入れた後に評価
    if (a <= l && r <= b) {
      // cout<<a<<"<="<<l<<" "<<r<<"<="<<b<<endl;
      // lazy[k] = x;
      lazy[k] = max(lazy[k], x);
      eval(k, l, r);
    }

    // そうでないならば、子ノードの値を再帰的に計算して、
    // 計算済みの値をもらってくる
    else {
      // add(a, b, x, 2*k+1, l, (l+r)/2);
      // add(a, b, x+(r-l)/2, 2*k+2, (l+r)/2, r);
      // add(a, b, x+(l+r)/2-a, 2*k+2, (l+r)/2, r);

      add(a, b, x, 2 * k + 1, l, (l + r) / 2);
      add(a, b, x + max((l + r) / 2 - a, 0), 2 * k + 2, (l + r) / 2, r);

      // add(a, min(b,(l+r)/2), x, 2*k+1, l, (l+r)/2);
      // add((max(a,l+r)/2), b, (x+(l+r)/2-a>=0?x+(l+r)/2-a:x) , 2*k+2, (l+r)/2,
      // r);

      // 建前としてab固定でよくて, xがどうなるか: 右区間で x->x+(l+r)/2-a
      // となるが, 負になることがある c=(l+r/2)として, a c  の時 右区間[c,r)は,
      // c-aだけx が増えてほしい
      //                   c aの時 右区間はそのままのxでいい

      // assert(x+(l+r)/2-a>=0);
      node[k] = min(node[2 * k + 1], node[2 * k + 2]);
    }
    ///        a  b
    ///     l        r
    ///     l    rl    r
  }
  ll getsum(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (b <= l || r <= a)
      return inf;

    // 関数が呼び出されたら評価！
    eval(k, l, r);
    if (a <= l && r <= b)
      return node[k];
    ll vl = getsum(a, b, 2 * k + 1, l, (l + r) / 2);
    ll vr = getsum(a, b, 2 * k + 2, (l + r) / 2, r);
    return min(vl, vr);
  }
};

class test {
public:
  ll W, H;
  vector<ll> A, B;
  vector<ll> ans;
  test(ll h, ll w, vector<ll> a, vector<ll> b) : H(h), W(w), A(a), B(b) {

    vector<vector<ll>> T(H + 1, vector<ll>(W, 0));
    ans = vector<ll>(H, inf);

    for (int i = 1; i <= H; i++) {

      for (int j = 0; j < W; j++) {
        T[i][j] =
            (A[i - 1] - 1 <= j && j <= B[i - 1] - 1)
                ? (A[i - 1] > 1 ? T[i - 1][A[i - 1] - 2] + j - A[i - 1] + 2
                                : inf)
                : T[i - 1][j];
        ans[i - 1] = min(ans[i - 1], T[i][j]);
      }

      if (ans[i - 1] >= inf)
        ans[i - 1] = -1;
      else
        ans[i - 1] += i;
    }
  }
};

int main() {
  ll H, W;
  cin >> H >> W; // inf=H+W;
  vector<ll> A(H), B(H);
  for (ll i = 0; i < H; i++)
    cin >> A[i] >> B[i];

  // ll H=10,W=100000;srand((unsigned int)time(NULL));
  // vector<ll>A(H),B(H);for(ll i=0;i<H;i++){A[i]=rand()%W+1;B[i]=rand()%W+1;}

  // LazySegmentTree lst(vector<ll>(W,0));

  // cout<<endl;

  test t(H, W, A, B);
  for (ll i = 0; i < H; i++) {
    // if(A[i]>1)lst.add(A[i]-1,B[i],1+lst.getsum(A[i]-2,A[i]-1));
    // else lst.add(0,B[i],inf);
    // ll x=lst.getsum(0,W)+i+1;
    // cout<<((x<inf?x:-1)==t.ans[i])<<endl;
    cout << t.ans[i] << endl;

    // cout<<(x<inf?x:-1)<<endl;
    // assert(x>=-100);
    // cout<<lst.getsum(0,W)+i+1<<endl;
    // cout<<" "<<(A[i]>1?1+lst.getsum(A[i]-2,A[i]-1):-1)<<endl;
    // cout<<" "<<(A[i]>1?A[i]-1:-1)<<endl;
    // for(long j=0;j<W;j++)cout<<lst.getsum(j,j+1)<<" ";cout<<endl;
  }
}

/*

移動回数を持たせる
遅延は,
[この区間はQから初めて1ずつ上がります]
という意味にすればいい




*/