思路:如果不存在 (le[i]==r[i + 1]) 的情况,这题 (for) 一遍就好了,当存在 (le[i]==r[i + 1]) 的情况时,我们没有时间更换弹夹就会开始下一波,所以我们要求出在每一波开始时弹匣里子弹最少所需的容量 (dp[i]) ,由于可能存在连续的 (le[i]==r[i + 1]) 的情况,所以我们从后往前遍历,求出 (dp[i]) ,然后如果碰到不可能的情况直接输出 (-1) 结束,然后正着遍历一遍就可以解决了。
#include <bits/stdc++.h>
using namespace std;
#define lc (rt << 1)
#define rc ((rt << 1) | 1)
#define fi first
#define se second
#define pb push_back
#define pii pair<int, int>
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define per(i, r, l) for (int i = (r); i >= (l); --i)
#define PE(i, u) for (int i = head[u]; i != -1; i = edge[i].next)
typedef long long LL;
const int maxn = 1e6 + 20;
const int mod = 1e9 + 7;
int n, m;
int le[maxn], ri[maxn], a[maxn], dp[maxn];
int main(int argc, char const *argv[])
{
scanf("%d%d", &n, &m);
rep(i, 1, n){
scanf("%d%d%d", &le[i], &ri[i], &a[i]);
}
per(i, n, 1){
int need = a[i];
if(i + 1 <= n && ri[i] == le[i + 1]){
need += dp[i + 1];
}
if(need > 1LL * (ri[i] - le[i] + 1) * m){
printf("-1
");
return 0;
}
dp[i] = max(0LL, need - 1LL * (ri[i] - le[i]) * m);
}
LL ans = 0;
int lim = m;
rep(i, 1, n){
if(lim < dp[i]){
ans += lim;
lim = m;
}
ans += a[i];
if(lim > a[i]) lim -= a[i];
else lim = m - (a[i] - lim) % m;
}
printf("%I64d
", ans);
return 0;
}