Problem p01683 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define INF 1LL << 60
using namespace std;
typedef long long ll;
typedef pair<ll, ll> P;
typedef pair<P, int> PP;

ll labs(ll v) {
  if (v < 0LL)
    return -v;
  return v;
}

int n;
ll dp[4001][4001];
vector<ll> d1;
vector<P> vec;

void solve() {
  d1.clear();
  vec.clear();
  ll sum = 2;
  for (int i = 0; i < n; i++) {
    int p, d;
    scanf("%d%d", &p, &d);
    sum += d - 2;
    if (d == 1) {
      d1.push_back(p);
    } else {
      vec.push_back(P(p, d));
    }
  }
  sort(d1.begin(), d1.end());
  sort(vec.begin(), vec.end());
  if (sum < 0) {
    printf("-1\\n");
    return;
  }
  if (vec.size() == 0) {
    printf("%lld\\n", d1[1] - d1[0]);
    return;
  }
  for (int i = 0; i <= d1.size(); i++) {
    dp[0][i] = INF;
  }
  dp[0][0] = 0;
  for (int i = 0; i < vec.size(); i++) {
    // cout << vec[i].first << " "<< vec[i].second << endl;
    int rest = vec[i].second - 2;
    if (i == 0) {
      rest++;
    }
    if (i + 1 == vec.size()) {
      rest++;
    }
    for (int j = 0; j <= d1.size(); j++) {
      dp[i + 1][j] = dp[i][j];
    }
    deque<PP> deq;
    ll lazysum = 0;
    for (int j = 0; j < d1.size(); j++) {
      if (rest == 0)
        break;
      while (deq.size() > 0 && deq[0].second < j + 1 - rest) {
        deq.pop_front();
      }
      while (deq.size() > 0 &&
             deq.back().first.first + lazysum - deq.back().first.second >=
                 dp[i][j]) {
        deq.pop_back();
      }
      deq.push_back(PP(P(dp[i][j], lazysum), j));
      lazysum += labs(d1[j] - vec[i].first);
      dp[i + 1][j + 1] = min(dp[i + 1][j + 1], deq[0].first.first + lazysum -
                                                   deq[0].first.second);
    }
  }
  /*
  for(int i=0;i<=vec.size();i++){
          for(int j=0;j<=d1.size();j++){
                  printf("%lld ",dp[i][j]);
          }
          printf("\\n");
  }
  */
  printf("%lld\\n",
         dp[vec.size()][d1.size()] + vec[vec.size() - 1].first - vec[0].first);
}

int main(void) {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;
    solve();
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define INF 1LL << 60
using namespace std;
typedef long long ll;
typedef pair<ll, int> P;

class segtree {
public:
  static const int N = 1 << 12;
  ll dp[1 << 13];
  ll lazy[1 << 13];
  segtree() {
    memset(dp, 0, sizeof(dp));
    memset(lazy, 0, sizeof(lazy));
  }

  void init() {
    memset(dp, 0, sizeof(dp));
    memset(lazy, 0, sizeof(lazy));
  }

  void lazy_eval(int k) {
    dp[k] += lazy[k];
    if (k < N - 1) {
      lazy[k * 2 + 1] += lazy[k];
      lazy[k * 2 + 2] += lazy[k];
    }
    lazy[k] = 0;
  }

  void lazy_upd(int k) { dp[k] = min(dp[k * 2 + 1], dp[k * 2 + 2]); }

  void update(int a, int b, ll v, int k = 0, int l = 0, int r = N) {
    lazy_eval(k);
    if (b <= l || r <= a)
      return;
    if (a <= l && r <= b) {
      lazy[k] += v;
      lazy_eval(k);
      return;
    }
    int mid = (l + r) / 2;
    update(a, b, v, k * 2 + 1, l, mid);
    update(a, b, v, k * 2 + 2, mid, r);
    lazy_upd(k);
  }

  ll query(int a, int b, int k = 0, int l = 0, int r = N) {
    lazy_eval(k);
    if (b <= l || r <= a)
      return INF;
    if (a <= l && r <= b)
      return dp[k];
    int mid = (l + r) / 2;
    ll vl = query(a, b, k * 2 + 1, l, mid);
    ll vr = query(a, b, k * 2 + 2, mid, r);
    lazy_upd(k);
    return min(vl, vr);
  }
};

ll labs(ll v) {
  if (v < 0LL)
    return -v;
  return v;
}

int n;
ll dp[4001][4001];
vector<ll> d1;
vector<P> vec;
segtree seg;

void solve() {
  d1.clear();
  vec.clear();
  ll sum = 2;
  for (int i = 0; i < n; i++) {
    int p, d;
    scanf("%d%d", &p, &d);
    sum += d - 2;
    if (d == 1) {
      d1.push_back(p);
    } else {
      vec.push_back(P(p, d));
    }
  }
  sort(d1.begin(), d1.end());
  sort(vec.begin(), vec.end());
  if (sum < 0) {
    printf("-1\\n");
    return;
  }
  if (vec.size() == 0) {
    printf("%lld\\n", d1[1] - d1[0]);
  }
  for (int i = 0; i <= d1.size(); i++) {
    dp[0][i] = INF;
  }
  dp[0][0] = 0;
  for (int i = 0; i < vec.size(); i++) {
    seg.init();
    for (int j = 0; j <= d1.size(); j++) {
      seg.update(j, j + 1, dp[i][j]);
    }
    int rest = vec[i].second - 2;
    if (i == 0 || i + 1 == vec.size()) {
      rest++;
    }
    for (int j = 0; j <= d1.size(); j++) {
      dp[i + 1][j] = dp[i][j];
    }
    for (int j = 0; j < d1.size(); j++) {
      seg.update(0, j + 1, labs(d1[j] - vec[i].first));
      ll val = seg.query(max(0, j + 1 - rest), j + 1);
      dp[i + 1][j + 1] = min(val, dp[i + 1][j + 1]);
    }
  }
  /*
  for(int i=0;i<=vec.size();i++){
          for(int j=0;j<=d1.size();j++){
                  printf("%lld ",dp[i][j]);
          }
          printf("\\n");
  }
  */
  printf("%lld\\n",
         dp[vec.size()][d1.size()] + vec[vec.size() - 1].first - vec[0].first);
}

int main(void) {
  while (1) {
    scanf("%d", &n);
    if (n == 0)
      break;
    solve();
  }
  return 0;
}