另类50pts求调
查看原帖
另类50pts求调
416242
New_hope楼主2024/8/13 15:01

希望有大佬可以帮忙看看,应该是细节上哪里没弄好,式子应该是对的。写法是单调栈维护下凸壳。

#include <bits/stdc++.h>
#define _ 50005
using namespace std;
using ll = long long;
using db = long double;

int n;
ll L, w(1e18); 
ll C[_], sum[_], dp[_];

struct P { ll x, y; };

struct Convex
{
  int top, j;
  P q[_];

  void init() { top = 0, j = 0; }
  db K(P a, P b) { return (a.y - b.y) * 1.0 / (a.x - b.x); }
  ll cal(int jud, int i) { return q[jud].y - q[jud].x * (sum[i] + i); }
  void insert(P x) {
    while (top > 1 && K(x, q[top]) < K(q[top], q[top - 1])) top --;
    q[++top] = x;
  }
  int find(int i) {
    while (top && j < top && K(q[j], q[j + 1]) < (db)(sum[i] + i)) j ++;
    return j;
  } 
} slope;

ll A(ll x) { return x * x; }

int main()
{ 
  cin >> n >> L;
  for (int i = 1; i <= n; i ++) cin >> C[i];
  for (int i = 1; i <= n; i ++) sum[i] = sum[i - 1] + C[i];

  slope.init();
  for (int i = 1; i <= n; i ++) {
    int p = slope.find(i);
    dp[i] = dp[i - 1] + A(C[i] - L);
    if (p) dp[i] = min(slope.cal(p, i) + A(i + sum[i] - L), dp[i]);
    ll x = 2 * (i + sum[i - 1]), 
       y = dp[i - 1] + 2 * L * (i + sum[i - 1]) + A(i + sum[i - 1]);
    slope.insert((P){x, y});
    // cout << dp[i] << "#\n";
  }
  cout << dp[n];

  return 0;
}
/*
g++ P3195.cpp -o P3195.exe -O2 -std=c++11

5 4
3
4
2
1
4
*/
2024/8/13 15:01
加载中...