【非原创】codeforces 1070C Cloud Computing 【线段树&树状数组】

题目:戳这里

学习博客:戳这里

题意:有很多个活动,每个活动有持续天数,每个活动会在每天提供C个CPU每个CPU价格为P,问需要工作N天,每天需要K个CPU的最少花费。

解题思路:遍历每一天,维护当前天K个cpu的最小花费。具体方法是维护两个线段树(树状数组也可以),维护每一天可以使用的cpu数和价格*cpu数的前缀和。注意数组下标是价格(1e6的数组。

(不明白的话可以看代码,代码思路很清晰

附学习博客的代码:

  1 #include <iostream>
  2 
  3 #include <algorithm>
  4 
  5 #include <string.h>
  6 
  7 #include <vector>
  8 
  9 #include <memory.h>
 10 
 11 #include <bitset>
 12 
 13 #include <map>
 14 
 15 #include <deque>
 16 
 17 #include <math.h>
 18 
 19 #include <stdio.h>
 20 
 21 using namespace std;
 22 
 23 typedef long long int ll;
 24 
 25 const int MAXN = 1000005;
 26 
 27  
 28 
 29 ll num[MAXN<<2];
 30 
 31 ll sum[MAXN<<2];
 32 
 33 int N;
 34 
 35 void pushup(int rt){
 36 
 37     num[rt]=num[rt<<1]+num[rt<<1|1];
 38 
 39     sum[rt]=sum[rt<<1]+sum[rt<<1|1];
 40 
 41 }
 42 
 43  
 44 
 45 void update(int P,int C,int l,int r,int rt){
 46 
 47     if(l==r){
 48 
 49         num[rt]+=C;
 50 
 51         sum[rt]+=1ll*P*C;
 52 
 53         return;
 54 
 55     }
 56 
 57  
 58 
 59     int m=(l+r)/2;
 60 
 61  
 62 
 63     if(P<=m)
 64 
 65         update(P,C,l,m,rt<<1);
 66 
 67     else
 68 
 69         update(P,C,m+1,r,rt<<1|1);
 70 
 71     pushup(rt);
 72 
 73 }
 74 
 75  
 76 
 77 ll query(int K,int l,int r,int rt){
 78 
 79  
 80 
 81     if(l==r){
 82 
 83         //不到K个
 84 
 85         if(l==MAXN){
 86 
 87             return 0;
 88 
 89         }
 90 
 91         if(K>0)
 92 
 93         {
 94 
 95             return 1ll*K*l;
 96 
 97         }
 98 
 99         else
100 
101             return 0;
102 
103     }
104 
105     int m=(l+r)/2;
106 
107     if(num[rt<<1]>=K){
108 
109         return query(K,l,m,rt<<1);
110 
111     }
112 
113     else{
114 
115         return sum[rt<<1]+query(K-num[rt<<1],m+1,r,rt<<1|1);
116 
117     }
118 
119 }
120 
121  
122 
123 vector<pair<int,int> > C[MAXN];//第i天加入的活动
124 
125 vector<pair<int,int> > O[MAXN];//第i天结束的活动
126 
127  
128 
129 int main()
130 
131 {
132 
133     int K,M;
134 
135     scanf("%d%d%d",&N,&K,&M);
136 
137  
138 
139     int l,r,c,p;
140 
141     for(int i=0;i<M;i++){
142 
143         scanf("%d%d%d%d",&l,&r,&c,&p);
144 
145         C[l].push_back(make_pair(p,c));//加入的活动
146 
147         O[r].push_back(make_pair(p,c));//退出的活动
148 
149     }
150 
151  
152 
153     ll ans=0;
154 
155     for(int i=1;i<=N;i++){
156 
157         //新活动加入
158 
159         for(int j=0;j<C[i].size();j++)
160 
161             update(C[i][j].first,C[i][j].second,1,MAXN,1);
162 
163         ans+=query(K,1,MAXN,1);
164 
165         //活动结束
166 
167         for(int j=0;j<O[i].size();j++)
168 
169             update(O[i][j].first,-O[i][j].second,1,MAXN,1);
170 
171     }
172 
173     cout<<ans<<endl;
174 
175  
176 
177     return 0;
178 
179 }
View Code

 

posted @ 2018-10-31 22:18  euzmin  阅读(196)  评论(0编辑  收藏  举报