while (head < rear && (Y(deque[rear]) - Y(deque[rear - 1])) * (X(i) - X(deque[rear])) >= (Y(i) - Y(deque[rear])) * (X(deque[rear]) - X(deque[rear - 1]))) rear--;
// AC
while (head < rear && (Y(deque[rear]) - Y(deque[rear - 1])) * (X(i) - X(deque[rear - 1])) >= (Y(i) - Y(deque[rear - 1])) * (X(deque[rear]) - X(deque[rear - 1]))) rear--;
// WA
为什么选取 rear 和 i 计算斜率就能够AC,但是选取 rear - 1 和 i 就会WA两个点qwq。
完整代码[AC]:
#include<cstdio>
#include<algorithm>
#define MAXN 300005
using namespace std;
typedef long long ll;
ll F[MAXN], sumT[MAXN], sum[MAXN], S, n;
int deque[MAXN], head, rear;
inline ll Y(int a) { return F[a] - S * sum[a]; }
inline ll X(int a) { return sum[a]; }
inline int binary_search(int L, int R, ll x) {
if (L == R) return deque[L];
int ans = R, mid; R--;
while (L <= R) {
mid = (L + R) / 2;
int m1 = deque[mid], m2 = deque[mid + 1];
if (Y(m2) - Y(m1) > x * (X(m2) - X(m1))) R = mid - 1, ans = mid;
else L = mid + 1;
}
return deque[ans];
}
int main() {
scanf("%lld %lld", &n, &S);
for (int i = 1; i <= n; ++i) {
scanf("%lld %lld", sumT + i, sum + i);
sumT[i] += sumT[i - 1], sum[i] += sum[i - 1];
}
for (int i = 1; i <= n; ++i) {
int j = binary_search(head, rear, sumT[i]);
F[i] = F[j] + sumT[i] * (sum[i] - sum[j]) + S * (sum[n] - sum[j]);
while (head < rear && (Y(deque[rear]) - Y(deque[rear - 1])) * (X(i) - X(deque[rear])) >= (Y(i) - Y(deque[rear])) * (X(deque[rear]) - X(deque[rear - 1]))) rear--;
deque[++rear] = i;
}
printf("%lld", F[n]);
return 0;
}