权值线段树

 

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
11 #include
12 #include
13 #include
14 #include
15 #include
16 #include
17 #include<set>
18 #include<string>
19 #include
20 #include
21 #include
22 //#include
23 #define vi vector
24 #define pii pair
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 vectorV[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<endl;
95     return 0;
96 }
View Code

 

你可能感兴趣的:(权值线段树)