首页 > 其他分享 >[题解]CF1070C Cloud Computing

[题解]CF1070C Cloud Computing

时间:2024-06-24 12:33:30浏览次数:3  
标签:cnt return Computing int 题解 tr query CPU Cloud

思路

考虑用线段树维护区间信息:

  1. 价格在 \([l,r]\) 之间的 CPU 的数量。

  2. 购买所有价格在 \([l,r]\) 之间 CPU 所需的钱。

容易将区间修改转化为差分,从而实现单点修改。于是可以使用 \(n\) 个 vector 存储第 \(i\) 天所需进行的修改。

查询第 \(i\) 天的答案时,如果不足 \(k\) 个 CPU 则直接选完所有的 CPU;否则贪心地选择价格前 \(k\) 小的 CPU。

这里实现的方法是,先求出第 \(k\) 小的值 \(x\),将小于 \(x\) 的所有 CPU 全部卖掉,然后剩下的用 \(x\) 补满 \(k\) 即可。

Code

#include <bits/stdc++.h>
#define fst first
#define snd second
#define re register
#define int long long

using namespace std;

typedef pair<int,int> pii;
const int N = 1e6 + 10;
int n,k,m,ans;
vector<pii> Q[N];

inline int read(){
    int r = 0,w = 1;
    char c = getchar();
    while (c < '0' || c > '9'){
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9'){
        r = (r << 3) + (r << 1) + (c ^ 48);
        c = getchar();
    }
    return r * w;
}

struct seg{
    #define ls(u) (u << 1)
    #define rs(u) (u << 1 | 1)

    struct node{
        int l,r;
        int cnt,sum;
    }tr[N << 2];

    inline void pushup(int u){
        tr[u].cnt = tr[ls(u)].cnt + tr[rs(u)].cnt;
        tr[u].sum = tr[ls(u)].sum + tr[rs(u)].sum;
    }

    inline void build(int u,int l,int r){
        tr[u] = {l,r};
        if (l == r) return;
        int mid = l + r >> 1;
        build(ls(u),l,mid),build(rs(u),mid + 1,r);
    }

    inline void modify(int u,int x,int k){
        if (tr[u].l == x && tr[u].r == x){
            tr[u].cnt += k;
            tr[u].sum = tr[u].cnt * x;
            return;
        }
        int mid = tr[u].l + tr[u].r >> 1;
        if (x <= mid) modify(ls(u),x,k);
        if (x > mid) modify(rs(u),x,k);
        pushup(u);
    }

    inline int query_kth(int u,int k){
        if (tr[u].l == tr[u].r) return tr[u].l;
        if (tr[ls(u)].cnt < k) return query_kth(rs(u),k - tr[ls(u)].cnt);
        else return query_kth(ls(u),k);
    }

    inline int query_cnt(int u,int l,int r){
        if (l <= tr[u].l && tr[u].r <= r) return tr[u].cnt;
        int res = 0;
        int mid = tr[u].l + tr[u].r >> 1;
        if (l <= mid) res += query_cnt(ls(u),l,r);
        if (r > mid) res += query_cnt(rs(u),l,r);
        return res;
    }

    inline int query_sum(int u,int l,int r){
        if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
        int res = 0;
        int mid = tr[u].l + tr[u].r >> 1;
        if (l <= mid) res += query_sum(ls(u),l,r);
        if (r > mid) res += query_sum(rs(u),l,r);
        return res;
    }

    inline int get(){
        if (tr[1].cnt <= k) return tr[1].sum;
        int kth = query_kth(1,k);
        int rk = query_cnt(1,1,kth - 1);
        return query_sum(1,1,kth - 1) + (k - rk) * kth;
    }

    #undef ls
    #undef rs
}T;

signed main(){
    n = read(),k = read(),m = read();
    T.build(1,1,1e6);
    for (re int i = 1;i <= m;i++){
        int l,r,c,p;
        l = read(),r = read(),c = read(),p = read();
        Q[l].push_back({c,p}),Q[r + 1].push_back({-c,p});
    }
    for (re int i = 1;i <= n;i++){
        for (auto p:Q[i]) T.modify(1,p.snd,p.fst);
        ans += T.get();
    }
    printf("%lld",ans);
    return 0;
}

标签:cnt,return,Computing,int,题解,tr,query,CPU,Cloud
From: https://www.cnblogs.com/WaterSun/p/18264790

相关文章

  • [题解]CF1746B Rebellion
    思路首先我们需要看到题目一个特殊的地方:这个序列中只存在\(0\)和\(1\)。那么,我们不难发现最终的答案一定是形如下面的序列:\(0,\dots,0,1,\dots,1\)。知道了这些,就很好想了。我们从后往前枚举,如果当前一位为\(0\)了,就从\(last\simi\)扫一遍,如果有\(1\)将最靠前的\(......
  • [题解]CF1742G Orray
    思路做这道题之前,首先要知道一个性质:\(a\operatorname{or}b\geqa\)。那么,我们就能得出一个结论:经过一定顺序的排列,最多经过\(\lceil\log_2^{a_{\max}}\rceil\)个数就能让前缀或的值达到最大值。我们不妨令有一个位置\(i\),\(b_1,b_2,\dots,b_{i-1}\)单调递增,而\(b_i......
  • [题解]CF1742E Scuza
    2022/11/23:修改了一下代码。题意有\(T\)组数据,每次给出一个\(n,q\),表示台阶的数量和询问的次数。然后再给出一个\(a_i\)为台阶高度的差分数组。每次询问给出一个\(k\),表示每次能走\(k\)个单位的高度。问:最高能到达的高度。思路考虑暴力,我们知道了高度的差分数组,那......
  • [题解]CF1741D Masha and a Beautiful Tree
    思路我们可以观察样例,不难发现:对于任意一段长度为\(2^k\)的区间中,如果最大值减最小值加\(1\)等于此区间的长度,那么一定有解。因为,我们的目标是使整个序列升序排列。因此,我们在一个区间内的最大值减最小值加\(1\)与区间长度是相等的。所以,我们可以用上述结论为判断无解的......
  • [题解]CF1741B Funny Permutation
    思路简单构造题,我们可以分为三种情况进行构造。\(n=3\)时,一定无解,输出-1。(你可以试试)\(n\bmod2=1\wedgen\neq3\)时,我们直接先输出\(n,n-1\),然后顺序输出即可。证明:令\(a\)为最后构造出的序列。那么,\(a_1=n,a_2=n-1,a_i=i-2(3\leqi\leq......
  • [题解]CF1732C2 Sheikh (Hard Version)
    思路首先证明一下当序列扩大时答案一定不劣。考虑\(f(l,r)\)到\(f(l,r+1)\)的变化。\[\begin{aligned}f(l,r)-f(l,r+1)&=s_{l,r}-xs_{l,r}-s_{l,r+1}+xs_{l,r+1}\\&=xs_{l,r+1}-xs_{l,r}-a_{r+1}\\&......
  • fdisk时WARNING: Re-reading the partition table failed with error 16: 设备或资源
    WARNING:Re-readingthepartitiontablefailedwitherror16:设备或资源现象:划分磁盘有警告, WARNING:Re-readingthepartitiontablefailedwitherror16:设备或资源忙.Thekernelstillusestheoldtable.Thenewtablewillbeusedatthenextrebootoraft......
  • 基于 Cloudflare Workers 和 cloudflare-docker-proxy 搭建镜像加速服务
    本文主要介绍了如何基于CloudflareWorkers和cloudflare-docker-proxy搭建dockerhub、gcr、quay等镜像加速服务。最近,受限于各种情况,部分主流镜像站都关了,为了能够正常使用,建议自己搭建一个加速器。写文之前,也已经部署好了一个,可以直接使用,具体使用方法跳转https://docke......
  • P3974 [TJOI2015] 组合数学 题解
    Description给一个网格图,其中某些格子有一些财宝。每次从左上角出发,只能往右或下走,每一次经过一个格子至多只能捡走一块财宝,至少要走几次才可能把财宝全捡完?\(1\leqn\leq1000\),\(1\leqm\leq1000\),每个格子中的财宝不超过\(10^6\)块。Solution考虑把每个点\((i,j)\)......
  • [题解]CF1066E Binary Numbers AND Sum
    思路考虑对于每一个\(a\)上数位进行分析。令\(a_i\)表示\(a\)在二进制表示中从左往右数的第\(i\)位上的数字,\(b_i\)同理。分类讨论一下\(a_i\)的取值对于答案的贡献:如果\(a_i=0\),对于这一位无论如何都不会拥有贡献。如果\(a_i=1\),因为\(b\)会向右移,所以能......