权值线段树
https://blog.csdn.net/lzc504603913/article/details/83240651
题意:有很多个活动,每个活动有持续天数,每个活动会在每天提供C个CPU每个CPU价格为P,问需要工作N天,每天需要K个CPU的最少花费。
解题思路:首先价格越低的活动,肯定是要选的。因此我们对于每一天记录有哪些新活动 加入,哪些活动结束。然后维护一个线段树,线段树的下标是价格。即价格为i的活动,一共能提供多少个CPU,然后加入和删除活动就相当于update(C,+-P,1,MAXC,1)。 然后我们顺便维护一下价格*数量的和。然后利用线段树天然的二分性,快速求出前缀数量和为K的价格和。
1 /************************************************************************* 2 > File Name: a.cpp 3 > Author: QWX 4 > Mail: 5 > Created Time: 2018/11/19 22:39:42 6 ************************************************************************/ 7 8 9 //{{{ #include 10 #include<iostream> 11 #include<cstdio> 12 #include<algorithm> 13 #include<vector> 14 #include<cmath> 15 #include<queue> 16 #include<map> 17 #include<set> 18 #include<string> 19 #include<cstring> 20 #include<complex> 21 #include<cassert> 22 //#include<bits/stdc++.h> 23 #define vi vector<int> 24 #define pii pair<int,int> 25 #define mp make_pair 26 #define pb push_back 27 #define fi first 28 #define se second 29 #define pw(x) (1ll << (x)) 30 #define sz(x) ((int)(x).size()) 31 #define all(x) (x).begin(),(x).end() 32 #define rep(i,l,r) for(int i=(l);i<(r);i++) 33 #define per(i,r,l) for(int i=(r);i>=(l);i--) 34 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 35 #define cl(a,b) memset(a,b,sizeof(a)) 36 #define fastio ios::sync_with_stdio(false);cin.tie(0); 37 #define lson l , mid , ls 38 #define rson mid + 1 , r , rs 39 #define INF 0x3f3f3f3f 40 #define LINF 0x3f3f3f3f3f3f3f3f 41 #define ll long long 42 #define ull unsigned long long 43 #define dd(x) cout << #x << " = " << (x) << "," 44 #define de(x) cout << #x << " = " << (x) << "\n" 45 #define endl "\n" 46 using namespace std; 47 //}}} 48 const int N=1e6+7; 49 50 struct Set{ 51 #define ls rt<<1 52 #define rs ls|1 53 static const int N=::N<<2; 54 ll sum[N],cnt[N]; 55 void up(int rt){ 56 cnt[rt]=cnt[ls]+cnt[rs]; 57 sum[rt]=sum[ls]+sum[rs]; 58 } 59 void upd(int p,ll c,int l,int r,int rt){ 60 if(l==r){ 61 cnt[rt]+=c; 62 sum[rt]=cnt[rt]*l; 63 return ; 64 } 65 int mid=l+r>>1; 66 if(p<=mid)upd(p,c,l,mid,ls); 67 else upd(p,c,mid+1,r,rs); 68 up(rt); 69 } 70 ll qry(ll k,int l,int r,int rt){ 71 if(cnt[rt]<=k)return sum[rt]; 72 int mid=l+r>>1; 73 if(l==r)return k*l; 74 if(cnt[ls]>=k)return qry(k,l,mid,ls); 75 return sum[ls]+qry(k-cnt[ls],mid+1,r,rs); 76 } 77 }seg; 78 vector<pii>V[N]; 79 80 int main() 81 { 82 int n,k,m; cin>>n>>k>>m; 83 ll ans=0; 84 rep(i,0,m){ 85 int a,b,c,d; cin>>a>>b>>c>>d; 86 V[a].pb(mp(c,d));V[b+1].pb(mp(-c,d)); 87 } 88 FOR(i,1,n){ 89 for(auto &t:V[i]){ 90 seg.upd(t.se,t.fi,1,1e6,1); 91 } 92 ans+=seg.qry(k,1,1e6,1); 93 } 94 cout<<ans<<endl; 95 return 0; 96 }