题目链接:传送门
思路:本来想的是直接给区间排序,后来发现太麻烦了,直接对每个点(一个区间有两个点)的贡献左区间计+c[i] , 负区间计-c[i] ,进行排序即可,每次访问下一个点的时候,首先计算i - 1 与 i 点之间的花费(此处与C进行比较,保证每天最多花C),把上一个点的贡献c[i - 1]计入新的c[i]。
做到这里,本题还有一个关键点:若一个区间为[l , r],l点的贡献从它自己l位置开始起效,而r点从r + 1点才开始起效,因此记录点的贡献时,右边坐标应为r + 1。为什么呢?比如下面这种情况: [1 , 3] , [ 3 , 5],很明显第一个3在位置4才开始起作用,所以计r + 1再排序才能得到正确答案。
c++代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
typedef long long ll;
ll a[maxn] , b[maxn] , c[maxn];
struct node {
ll p , d;
bool operator < (const node b) const {
return ( p < b.p ) || ( p == b.p && d > b.d ) ;
}
node(ll a , ll b) : p(a) , d(b){}
};
vector <node> v;
int main() {
int n;
ll C;
cin >> n;
cin >> C;
for(int i = 0 ; i < n ; i++) {
cin >> a[i] >> b[i] >> c[i];
v.push_back( node(b[i] + 1 , - c[i] ));
v.push_back( node(a[i] , c[i] ));
}
sort( v.begin() , v.end() );
ll ans = 0;
for(int i = 1 ; i < v.size() ; i++) {
int t = v[i].p - v[i - 1].p;
ans += min(C , v[i - 1].d) * t;
v[i].d += v[i - 1].d;
}
cout << ans << "\n";
return 0;
}