Cloud Computing 【CodeForces - 1070C】【线段树+思维】

题目链接


  题意:有这样连续的N天,每一天为了公司的运营,需要消耗的是K个CPU核心零件,我们有M个生产厂家,他们分别有这样的规则:在[l, r]这几天里工作,每天能捣鼓出最多C个零件,每个零件的售价是P元,问的是这N天最少需要消耗的金钱总数。

  思路:遇到这样的天数问题,又有多个条件,想到的就是利用差分的思想来存,在第L天的时候存入,第R+1天的时候取出,然后,我们可以看到价值的上限是1e6,这样我们不如直接去搜索区间内的前缀的最小价值,权值线段树来存,放入的是每个值的元素的个数,然后去查询前K大的所有的数的和。


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e6 + 7;
const int _UP = 1e6;
int N, K, M;
vector> vt[maxN];
struct node
{
    ll num, price;
    node(ll a = 0, ll b = 0):num(a), price(b) {}
}tree[maxN<<2];
inline void pushup(int rt) { tree[rt] = node(tree[lsn].num + tree[rsn].num, tree[lsn].price + tree[rsn].price); }
void update(int rt, int l, int r, ll pos, ll val)
{
    if(l == r)
    {
        tree[rt].num += val;
        tree[rt].price += pos * val;
        return;
    }
    int mid = HalF;
    if(pos <= mid) update(Lson, pos, val);
    else update(Rson, pos, val);
    pushup(rt);
}
ll query(int rt, int l, int r, ll Kth)
{
    if(tree[rt].num <= Kth) return tree[rt].price;
    if(l == r) return l * Kth;
    int mid = HalF;
    if(tree[lsn].num >= Kth) return query(Lson, Kth);
    else return query(Rson, Kth - tree[lsn].num) + tree[lsn].price;
}
int main()
{
    scanf("%d%d%d", &N, &K, &M);
    for(int i=1, L, R, C, P; i<=M; i++)
    {
        scanf("%d%d%d%d", &L, &R, &C, &P);
        vt[L].push_back(MP(C, P));
        vt[R+1].push_back(MP(-C, P));
    }
    ll ans = 0;
    for(int i=1; i<=N; i++)
    {
        for(auto it : vt[i]) update(1, 1, _UP, it.second, it.first);
        ans += query(1, 1, _UP, K);
    }
    printf("%lld\n", ans);
    return 0;
}

 

你可能感兴趣的:(线段树,数据结构)