Problem p03396 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const ll INF = (ll)1e18;
const int N = 300100;
ll a[N];
ll b[N];
ll c[N][3];
int n;
ll dp[2][N];
ll L;

int main() {
  //	freopen("input.txt", "r", stdin);
  //	freopen("output.txt", "w", stdout);

  scanf("%d%lld", &n, &L);
  for (int i = 1; i <= n; i++)
    scanf("%lld", &a[i]);
  for (int i = 1; i <= n; i++)
    scanf("%lld", &b[i]);
  a[n + 1] = L;
  for (int i = 1; i <= n; i++) {
    c[i][0] = c[i][1] = c[i][2] = INF;

    ll x = a[i] + b[i];
    if (x % (2 * L) > a[i])
      x += 2 * L;
    x += a[i] - (x % (2 * L));
    x -= a[i];
    c[i][1] = min(c[i][1], x);

    x = a[i] + b[i];
    if (x % (2 * L) > 2 * L - a[i])
      x += 2 * L;
    x += 2 * L - a[i] - (x % (2 * L));
    x -= a[i];
    c[i][0] = min(c[i][0], x);

    x = 2 * L - a[i] + b[i];
    if (x % (2 * L) > a[i])
      x += 2 * L;
    x += a[i] - (x % (2 * L));
    x -= 2 * L - a[i];
    c[i][2] = min(c[i][2], x);

    x = 2 * L - a[i] + b[i];
    if (x % (2 * L) > 2 * L - a[i])
      x += 2 * L;
    x += 2 * L - a[i] - (x % (2 * L));
    x -= 2 * L - a[i];
    c[i][1] = min(c[i][1], x);
  }

  int m = min(n, (int)5e8 / n);

  for (int i = 0; i <= m; i++)
    dp[0][i] = INF;
  dp[0][1] = 0;

  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= m; j++)
      dp[0][j] = min(INF, dp[0][j] + 2 * j * (a[i] - a[i - 1]));
    for (int j = 0; j <= m; j++)
      dp[1][j] = INF;
    for (int j = 1; j <= m; j++) {
      for (int x = 0; x < 3; x++)
        dp[1][j + x - 1] = min(dp[1][j + x - 1], dp[0][j] + c[i][x]);
    }
    for (int j = 0; j <= m; j++)
      dp[0][j] = dp[1][j];
  }

  ll ans = INF;
  for (int i = 0; i <= m; i++)
    ans = min(ans, dp[0][i] + 2 * i * (a[n + 1] - a[n]));
  printf("%lld\n", ans);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define eprintf(...) 42
#endif

typedef long long ll;
typedef pair<int, int> pii;
#define mp make_pair

const ll INF = (ll)1e18;
const int N = 300100;
ll a[N];
ll b[N];
ll c[N][3];
int n;
ll dp[2][N];
ll L;

int main() {
  //	freopen("input.txt", "r", stdin);
  //	freopen("output.txt", "w", stdout);

  scanf("%d%lld", &n, &L);
  for (int i = 1; i <= n; i++)
    scanf("%lld", &a[i]);
  for (int i = 1; i <= n; i++)
    scanf("%lld", &b[i]);
  a[n + 1] = L;
  for (int i = 1; i <= n; i++) {
    c[i][0] = c[i][1] = c[i][2] = INF;

    ll x = a[i] + b[i];
    if (x % (2 * L) > a[i])
      x += 2 * L;
    x += a[i] - (x % (2 * L));
    x -= a[i];
    c[i][1] = min(c[i][1], x);

    x = a[i] + b[i];
    if (x % (2 * L) > 2 * L - a[i])
      x += 2 * L;
    x += 2 * L - a[i] - (x % (2 * L));
    x -= a[i];
    c[i][0] = min(c[i][0], x);

    x = 2 * L - a[i] + b[i];
    if (x % (2 * L) > a[i])
      x += 2 * L;
    x += a[i] - (x % (2 * L));
    x -= 2 * L - a[i];
    c[i][2] = min(c[i][2], x);

    x = 2 * L - a[i] + b[i];
    if (x % (2 * L) > 2 * L - a[i])
      x += 2 * L;
    x += 2 * L - a[i] - (x % (2 * L));
    x -= 2 * L - a[i];
    c[i][1] = min(c[i][1], x);
  }

  int m = min(n, (int)2e8 / n);

  for (int i = 0; i <= m; i++)
    dp[0][i] = INF;
  dp[0][1] = 0;

  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= m; j++)
      dp[0][j] = min(INF, dp[0][j] + 2 * j * (a[i] - a[i - 1]));
    for (int j = 0; j <= m; j++)
      dp[1][j] = INF;
    for (int j = 1; j <= m; j++) {
      for (int x = 0; x < 3; x++)
        dp[1][j + x - 1] = min(dp[1][j + x - 1], dp[0][j] + c[i][x]);
    }
    for (int j = 0; j <= m; j++)
      dp[0][j] = dp[1][j];
  }

  ll ans = INF;
  for (int i = 0; i <= m; i++)
    ans = min(ans, dp[0][i] + 2 * i * (a[n + 1] - a[n]));
  printf("%lld\n", ans);

  return 0;
}