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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <typeinfo>
#include <vector>
#define syosu(x) fixed << setprecision(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<double, double> pdd;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<P> vp;
typedef vector<vp> vvp;
typedef vector<pll> vpll;
typedef pair<int, P> pip;
typedef vector<pip> vip;
const int inf = 1 << 29;
const ll INF = 1ll << 60;
const double pi = acos(-1);
const double eps = 1e-7;
const ll mod = 1e9 + 7;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};

class Union_Find_Tree {
public:
  vi Par;
  Union_Find_Tree(int n) {
    Par = vi(n);
    for (int i = 0; i < n; i++)
      Par[i] = i;
  }
  int Find_Par(int x) {
    if (Par[x] == x)
      return x;
    return Par[x] = Find_Par(Par[x]);
  }
  bool Unite(int x, int y) {
    x = Find_Par(x);
    y = Find_Par(y);
    if (x == y)
      return 0;
    Par[x] = y;
    return 1;
  }
};

int w, n;
vi a;

bool f(int x) {
  vi L(n), R(n);
  int li = 1, ri = 1, ls = a[0], rs = a[0];
  for (int i = 0; i < n; i++) {
    ls -= (i ? a[i - 1] + x : 0);
    while (li < n && ls < w) {
      ls += x + a[li];
      li++;
    }
    rs -= (i ? a[i - 1] + 1 : 0);
    while (ri < n && rs <= w) {
      rs += 1 + a[ri];
      ri++;
    }
    if (rs <= w && ri == n) {
      ri++;
    }
    L[i] = li;
    R[i] = ri;
  }
  Union_Find_Tree uft(n + 1);
  queue<int> q;
  q.push(0);
  while (!q.empty()) {
    int p = q.front();
    q.pop();
    if (R[p] == n + 1)
      return 1;
    int i = uft.Find_Par(L[p]);
    while (i < R[p]) {
      q.push(i);
      uft.Unite(i, i + 1);
      i = uft.Find_Par(i);
    }
  }
  return 0;
}

int main() {
  while (1) {
    cin >> w >> n;
    if (!w)
      break;
    a = vi(n);
    for (int i = 0; i < n; i++)
      cin >> a[i];
    int l = 0, r = w;
    while (r - l > 1) {
      int m = (l + r) / 2;
      if (f(m))
        r = m;
      else
        l = m;
    }
    cout << r << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <typeinfo>
#include <vector>
#define syosu(x) fixed << setprecision(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<double, double> pdd;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<P> vp;
typedef vector<vp> vvp;
typedef vector<pll> vpll;
typedef pair<int, P> pip;
typedef vector<pip> vip;
const int inf = 1 << 29;
const ll INF = 1ll << 60;
const double pi = acos(-1);
const double eps = 1e-7;
const ll mod = 1e9 + 7;
const int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};

int w, n;
vi a;

bool f(int x) {
  vi L(n), R(n);
  int li = 1, ri = 1, ls = a[0], rs = a[0];
  for (int i = 0; i < n; i++) {
    ls -= (i ? a[i - 1] + x : 0);
    while (li < n && ls < w) {
      ls += x + a[li];
      li++;
    }
    rs -= (i ? a[i - 1] + 1 : 0);
    while (ri < n && rs <= w) {
      rs += 1 + a[ri];
      ri++;
    }
    if (rs <= w && ri == n) {
      ri++;
    }
    L[i] = li;
    R[i] = ri;
  }
  vi used(n + 1);
  used[0] = 1;
  queue<int> q;
  q.push(0);
  while (!q.empty()) {
    int p = q.front();
    q.pop();
    if (R[p] == n + 1)
      return 1;
    for (int i = L[p]; i < R[p]; i++)
      if (!used[i]) {
        used[i] = 1;
        q.push(i);
      }
  }
  return 0;
}

int main() {
  while (1) {
    cin >> w >> n;
    if (!w)
      break;
    a = vi(n);
    for (int i = 0; i < n; i++)
      cin >> a[i];
    int l = 0, r = w;
    while (r - l > 1) {
      int m = (l + r) / 2;
      if (f(m))
        r = m;
      else
        l = m;
    }
    cout << r << endl;
  }
}