Problem p03187 (C++)

Buggy submission (status: Runtime Error):
/*
对应原理
其实每次只有两种选择，所有这个题的对拍很好写
怎么确定能不能达到最大值呢
跑步的速度是可以加快的，每次贪心选择能行吗
有一些能够拿两次，最终答案一定是要将什么拿两次的

最快的办法当然是永不回头，但是最慢的办法并不是一步一回头
我们要积累7+7+1=15
顺时针能够拿两次
为了把很大的一个数拿两次，必须他的补集中有能够回去的，并且那个数字一定是我右边紧邻的那个
为了拿到这一个7两次，顺时针必须留一个，
就意味着逆时针3次对应顺时针1次
并且必须先逆3
为了拿到这个4两次，顺时针留一个
则逆2顺2 且逆先
为了拿到3两次，顺时针留一个
逆1顺3

i n-i
当i<n-i时
左i 右(i+1)减去最左边 最后一次是顺时针
a[1...i]*2+((i+1)*2*n-a[i+1...i+i+1]*2)-(n-a[i+1]) 左i减去最右边 右i
最后一次是逆时针     a[1...i]*2+(i*2*n-a[i+1...i+i]*2)-a[i]

i=n-i时
左i右i 减去左或减去右
a[1...i]*2+(i*2*n-a[i+1...i+i]*2)-a[i]/a[1...i]*2+(i*2*n-a[i+1...i+i]*2)-a[i+1]
i>n-i时
左n-i+1减去最右边 右n-i
左n-i，右n-i减去最左边
*/
#include <bits/stdc++.h>
#define MAXN 205
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
const ll INF = 1e18;
ll l, n, x, sum[MAXN], a[MAXN], fin;
int main() {
  //    freopen("c://duipai//939cdata.txt", "r", stdin);
  //    freopen("c://duipai//939cwa.txt", "w", stdout);
  while (~scanf("%lld", &l)) {
    //        string str;
    //        cin>>str;
    //        cout<<str<<endl;
    scanf("%lld", &n);
    memset(sum, 0, sizeof(sum));
    fin = 0;
    for (ll i = 1; i <= n; i++) {
      scanf("%lld", &x);
      a[i] = x;
      sum[i] = sum[i - 1] + x;
    }
    if (n == 1) {
      printf("%lld\n", max(a[1], l - a[1]));
      continue;
    }
    for (ll i = 1; i < n; i++) {
      ll ans1, ans2;
      if (i < n - i) {
        ans1 = sum[i] * 2 + ((i + 1) * 2 * l - (sum[i + i + 1] - sum[i]) * 2) -
               (l - a[i + 1]);
        ans2 = sum[i] * 2 + (i * 2 * l - (sum[i + i] - sum[i]) * 2) - a[i];
      } else if (i == n - i) {
        ans1 = sum[i] * 2 + (i * 2 * l - (sum[i + i] - sum[i]) * 2) -
               (l - a[i + 1]);
        ans2 = sum[i] * 2 + (i * 2 * l - (sum[i + i] - sum[i]) * 2) - a[i];
      } else {
        ans1 = (sum[i] - sum[i - (n - i) - 1]) * 2 +
               ((n - i) * 2 * l - (sum[n] - sum[i]) * 2) - (a[i]);
        ans2 = (sum[i] - sum[i - (n - i)]) * 2 +
               ((n - i) * 2 * l - (sum[n] - sum[i]) * 2) - (l - a[i + 1]);
      }
      // printf("%lld %lld\n",ans1,ans2);
      ll ans = max(ans1, ans2);
      fin = max(fin, ans);
    }
    fin = max(fin, a[n]);
    fin = max(fin, l - a[1]);
    printf("%lld\n", fin);
  }
}
/*
 */


Fixed submission:
/*
对应原理
其实每次只有两种选择，所有这个题的对拍很好写
怎么确定能不能达到最大值呢
跑步的速度是可以加快的，每次贪心选择能行吗
有一些能够拿两次，最终答案一定是要将什么拿两次的

最快的办法当然是永不回头，但是最慢的办法并不是一步一回头
我们要积累7+7+1=15
顺时针能够拿两次
为了把很大的一个数拿两次，必须他的补集中有能够回去的，并且那个数字一定是我右边紧邻的那个
为了拿到这一个7两次，顺时针必须留一个，
就意味着逆时针3次对应顺时针1次
并且必须先逆3
为了拿到这个4两次，顺时针留一个
则逆2顺2 且逆先
为了拿到3两次，顺时针留一个
逆1顺3

i n-i
当i<n-i时
左i 右(i+1)减去最左边 最后一次是顺时针
a[1...i]*2+((i+1)*2*n-a[i+1...i+i+1]*2)-(n-a[i+1]) 左i减去最右边 右i
最后一次是逆时针     a[1...i]*2+(i*2*n-a[i+1...i+i]*2)-a[i]

i=n-i时
左i右i 减去左或减去右
a[1...i]*2+(i*2*n-a[i+1...i+i]*2)-a[i]/a[1...i]*2+(i*2*n-a[i+1...i+i]*2)-a[i+1]
i>n-i时
左n-i+1减去最右边 右n-i
左n-i，右n-i减去最左边
*/
#include <bits/stdc++.h>
#define MAXN 200005
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
const ll INF = 1e18;
ll l, n, x, sum[MAXN], a[MAXN], fin;
int main() {
  //    freopen("c://duipai//939cdata.txt", "r", stdin);
  //    freopen("c://duipai//939cwa.txt", "w", stdout);
  while (~scanf("%lld", &l)) {
    //        string str;
    //        cin>>str;
    //        cout<<str<<endl;
    scanf("%lld", &n);
    memset(sum, 0, sizeof(sum));
    fin = 0;
    for (ll i = 1; i <= n; i++) {
      scanf("%lld", &x);
      a[i] = x;
      sum[i] = sum[i - 1] + x;
    }
    if (n == 1) {
      printf("%lld\n", max(a[1], l - a[1]));
      continue;
    }
    for (ll i = 1; i < n; i++) {
      ll ans1, ans2;
      if (i < n - i) {
        ans1 = sum[i] * 2 + ((i + 1) * 2 * l - (sum[i + i + 1] - sum[i]) * 2) -
               (l - a[i + 1]);
        ans2 = sum[i] * 2 + (i * 2 * l - (sum[i + i] - sum[i]) * 2) - a[i];
      } else if (i == n - i) {
        ans1 = sum[i] * 2 + (i * 2 * l - (sum[i + i] - sum[i]) * 2) -
               (l - a[i + 1]);
        ans2 = sum[i] * 2 + (i * 2 * l - (sum[i + i] - sum[i]) * 2) - a[i];
      } else {
        ans1 = (sum[i] - sum[i - (n - i) - 1]) * 2 +
               ((n - i) * 2 * l - (sum[n] - sum[i]) * 2) - (a[i]);
        ans2 = (sum[i] - sum[i - (n - i)]) * 2 +
               ((n - i) * 2 * l - (sum[n] - sum[i]) * 2) - (l - a[i + 1]);
      }
      // printf("%lld %lld\n",ans1,ans2);
      ll ans = max(ans1, ans2);
      fin = max(fin, ans);
    }
    fin = max(fin, a[n]);
    fin = max(fin, l - a[1]);
    printf("%lld\n", fin);
  }
}
/*
 */