题目链接:Codeforces - Cloud Computing
每次我们需要取最小的k个,显然可以按照时间线添加商人的物品,然后权值线段树上面二分即可。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int n,k,m,sum[N<<2],num[N<<2],res,up=1e6;
vector<pair<int,int>> v[N];
void change(int p,int l,int r,int x,int v){
if(l==r){num[p]+=v,sum[p]+=x*v; return ;}
int mid=l+r>>1;
if(x<=mid) change(p<<1,l,mid,x,v);
else change(p<<1|1,mid+1,r,x,v);
num[p]=num[p<<1]+num[p<<1|1];
sum[p]=sum[p<<1]+sum[p<<1|1];
}
int ask(int p,int l,int r,int k){
if(num[p]<=k) return sum[p];
if(l==r) return k*l; int mid=l+r>>1;
if(num[p<<1]>=k) return ask(p<<1,l,mid,k);
else return sum[p<<1]+ask(p<<1|1,mid+1,r,k-num[p<<1]);
}
signed main(){
ios::sync_with_stdio(false),cin.tie(nullptr);
cin>>n>>k>>m;
for(int i=1,l,r,c,p;i<=m;i++){
cin>>l>>r>>c>>p; v[l].push_back({p,c}),v[r+1].push_back({p,-c});
}
for(int i=1;i<=n;i++){
for(auto j:v[i]) change(1,1,up,j.first,j.second);
res+=ask(1,1,up,k);
}
cout<<res;
return 0;
}