[codeforces1070C]Cloud Computing

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 ith tariff plan is characterized by the following parameters: l i li li and r i ri ri — the i − t h i-th ith 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 ith tariff plan,
p i p_i pi— the price of renting one core per day on the i − t h i-th ith 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) (1n,k106,1m2105) — 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(1lirin,1ci,pi106), where l i l_i li and r i r_i ri are starting and finishing days of the i − t h i-th ith 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 ith 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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值