time limit per test : 3 seconds
memory limit per test : 256 megabytes
Buber is a Berland technology company that specializes in waste of investor’s money. Recently Buber decided to transfer its infrastructure to a cloud. The company decided to rent CPU cores in the cloud for n
consecutive days, which are numbered from 1 to n. Buber requires k
CPU cores each day.
The cloud provider offers m
tariff plans, the
i
−
t
h
i-th
i−th tariff plan is characterized by the following parameters:
l
i
li
li and
r
i
ri
ri — the
i
−
t
h
i-th
i−th tariff plan is available only on days from
l
i
l_i
li to
r
i
r_i
ri, inclusive,
c
i
c_i
ci— the number of cores per day available for rent on the
i
−
t
h
i-th
i−th tariff plan,
p
i
p_i
pi— the price of renting one core per day on the
i
−
t
h
i-th
i−th tariff plan.
Buber can arbitrarily share its computing core needs between the tariff plans. Every day Buber can rent an arbitrary number of cores (from 0 to
c
i
c_i
ci) on each of the available plans. The number of rented cores on a tariff plan can vary arbitrarily from day to day.
Find the minimum amount of money that Buber will pay for its work for n n n days from 1 1 1 to n n n. If on a day the total number of cores for all available tariff plans is strictly less than k k k, then this day Buber will have to work on fewer cores (and it rents all the available cores), otherwise Buber rents exactly k k k cores this day.
Input
The first line of the input contains three integers
n
n
n,
k
k
k and
m
m
m
(
1
≤
n
,
k
≤
1
0
6
,
1
≤
m
≤
2
⋅
1
0
5
)
(1≤n,k≤10^6,1≤m≤2⋅10^5)
(1≤n,k≤106,1≤m≤2⋅105) — the number of days to analyze, the desired daily number of cores, the number of tariff plans.
The following
m
m
m lines contain descriptions of tariff plans, one description per line. Each line contains four integers
l
i
,
r
i
,
c
i
,
p
i
(
1
≤
l
i
≤
r
i
≤
n
,
1
≤
c
i
,
p
i
≤
1
0
6
)
l_i, r_i, c_i, p_i (1≤l_i≤r_i≤n, 1≤c_i,p_i≤10^6)
li,ri,ci,pi(1≤li≤ri≤n,1≤ci,pi≤106), where
l
i
l_i
li and
r
i
r_i
ri are starting and finishing days of the
i
−
t
h
i-th
i−th tariff plan,
c
i
c_i
ci — number of cores,
p
i
pi
pi — price of a single core for daily rent on the
i
−
t
h
i-th
i−th tariff plan.
Output
Print a single integer number — the minimal amount of money that Buber will pay.
Examples
Input
5 7 3
1 4 5 3
1 3 5 2
2 5 10 1
Output
44
Input
7 13 5
2 3 10 7
3 5 10 10
1 2 10 6
4 5 10 9
3 4 10 8
Output
462
Input
4 100 3
3 3 2 5
1 1 3 2
2 4 4 4
Output
64
题意:
有
m
m
m种借用云计算内核的方案,第
i
i
i种方案由
l
i
l_i
li,
r
i
r_i
ri,
c
i
c_i
ci,
p
i
p_i
pi来描述。
表示这种方案的可借用时间是从第
l
i
l_i
li天到第
r
i
r_i
ri天,每天这种方案提供至多
c
i
c_i
ci个内核,每个内核所要的租金是
p
i
p_i
pi
公司在这
n
n
n天内,每天如果能租到的内核个数小于
k
k
k,则全部租掉,否则租刚好
k
k
k个内核,请问过完这
n
n
n天,公司最少要花掉多少钱。
题解:
差分+线段树。
对于每一个内核使用方案分成(
l
i
l_i
li,
c
i
c_i
ci,
p
i
p_i
pi)和(
r
i
+
1
r_i+1
ri+1,
−
c
i
-c_i
−ci,
p
i
p_i
pi)两个方案,记为对
l
i
l_i
li有影响和对
r
i
+
1
r_i+1
ri+1有影响。
然后顺着从
1
1
1到
n
n
n扫一遍,对每个点插入所有有影响该点的方案。然后查询整个线段树,计算当前点的最小答案,这个只需要一个线段树查找即可,线段树每个结点记录当前单价在
L
L
L到
R
R
R的内核的数量,还有总价格。
#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
#define pa pair<int,int>
using namespace std;
int n,ks,m;
vector<pa>oc[1000004];
struct tree{
int l,r;
ll cn,cm;
}tr[4000004];
void build(int k,int l,int r){
tr[k].cn=0;tr[k].cm=0;
tr[k].l=l;tr[k].r=r;
if(l==r)return ;
int mid=(l+r)>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void add(int k,int c,int p){
int l=tr[k].l,r=tr[k].r;
tr[k].cn+=c;
tr[k].cm+=1LL*c*p;
if(l==r)return ;
int mid=(l+r)>>1;
if(p<=mid)add(k<<1,c,p);
else add(k<<1|1,c,p);
}
ll query(int k,ll v){
int l=tr[k].l,r=tr[k].r;
if(v<=0)return 0;
if(tr[k].cn<=v)return tr[k].cm;
if(l==r)return v*l;
int mid=(l+r)>>1;
return query(k<<1,min(v,tr[k<<1].cn))+query(k<<1|1,v-tr[k<<1].cn);
}
int w33ha(){
for(int i=0;i<=1000001;i++)oc[i].clear();
for(int i=1;i<=m;i++){
int l,r,c,p;scanf("%d%d%d%d",&l,&r,&c,&p);
oc[l].push_back(make_pair(c,p));
oc[r+1].push_back(make_pair(-c,p));
}
build(1,1,1000000);
ll ans=0;
for(int i=1;i<=n;i++){
for(int j=0;j<oc[i].size();j++){
add(1,oc[i][j].first,oc[i][j].second);
}
ans+=query(1,min(1LL*ks,tr[1].cn));
}
printf("%lld\n",ans);
return 0;
}
int LiangJiaJun(){
while(scanf("%d%d%d",&n,&ks,&m)!=EOF)w33ha();
return 0;
}