Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) E - Aquarium decoration 贪心 + 平衡树

E - Aquarium decoration

枚举两个人都喜欢的个数,就能得到单个喜欢的个数,然后用平衡树维护前k大的和。

#include<bits/stdc++.h>
#define LL long long
#define fi first
#define se second
#define mk make_pair
#define PII pair<int, int>
#define PLI pair<LL, int>
#define ull unsigned long long
using namespace std;

const int N = 2e5 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 998244353;
const int Mod = 1e9 + 7;

int n, m, k, num, cnt, state[N], d[N], a[N], b[N], c[N];
LL suma[N], sumb[N], sumc[N];

struct node {
    node* ch[2];
    int key, fix, sz, cnt;
    LL sum;
    void update() {
        sz = ch[0]->sz + ch[1]->sz + cnt;
        sum = ch[0]->sum + ch[1]->sum + 1ll*cnt*key;
    }
};

typedef node* P_node;

struct Treap {
    node base[N], nil;
    P_node root, null, len;
    Treap() {
        root = null = &nil;
        null->key = null->fix = 1e9;
        null->sz = null->cnt = 0;
        null->ch[0] = null->ch[1] = null;
        len = base;
    }
    P_node newnode(int tkey) {
        len->key = tkey;
        len->fix = rand();
        len->ch[0] = len->ch[1] = null;
        len->sz = len->cnt = 1;
        len->sum = tkey;
        return len++;
    }
    void rot(P_node &p, int d) {
        P_node k = p->ch[d ^ 1];
        p->ch[d ^ 1] = k->ch[d];
        k->ch[d] = p;
        p->update();
        k->update();
        p = k;
    }
    void _Insert(P_node &p, int tkey) {
        if(p == null) {
            p = newnode(tkey);
        } else if(p->key == tkey) {
            p->cnt++;
        } else {
            int d = tkey > p->key;
            _Insert(p->ch[d], tkey);
            if(p->ch[d]->fix > p->fix) {
                rot(p, d ^ 1);
            }
        }
        p->update();
    }

    void _Delete(P_node &p, int tkey) {
        if(p == null) return;
        if(p->key == tkey) {
            if(p->cnt > 1) p->cnt--;
            else if(p->ch[0] == null) p = p->ch[1];
            else if(p->ch[1] == null) p = p->ch[0];
            else {
                int d = p->ch[0]->fix > p->ch[1]->fix;
                rot(p, d);
                _Delete(p->ch[d], tkey);
            }
        } else {
            _Delete(p->ch[tkey > p->key], tkey);
        }
        p->update();
    }
    int _Kth(P_node p, int k) {
        if(p == null || k < 1 || k > p->sz) return 0;
        if(k < p->ch[0]->sz + 1) return _Kth(p->ch[0], k);
        if(k > p->ch[0]->sz + p->cnt) return _Kth(p->ch[1], k - p->ch[0]->sz - p->cnt);
        return p->key;
    }
    int _Rank(P_node p, int tkey, int res) {
        if(p == null) return -1;
        if(p->key == tkey) return p->ch[0]->sz + res + 1;
        if(tkey < p->key) return _Rank(p->ch[0], tkey, res);
        return _Rank(p->ch[1], tkey, res + p->ch[0]->sz + p->cnt);
    }
    int _Pred(P_node p, int tkey){
        if(p == null) return -1e9;
        if(tkey <= p->key) return _Pred(p->ch[0], tkey);
        return max(p->key, _Pred(p->ch[1], tkey));
    }
    int _Succ(P_node p, int tkey){
        if(p == null) return 1e9;
        if(tkey >= p->key) return _Succ(p->ch[1], tkey);
        return min(p->key, _Succ(p->ch[0], tkey));
    }
    LL _Query(P_node p, int res) {
        if(!res) return 0;
        if(p->ch[0]->sz >= res) return _Query(p->ch[0], res);
        else if(p->ch[0]->sz + p->cnt < res) {
            return p->ch[0]->sum + 1ll*p->key*p->cnt + _Query(p->ch[1], res - p->ch[0]->sz - p->cnt);
        } else {
            return p->ch[0]->sum + 1ll*p->key*(res - p->ch[0]->sz);
        }
    }
    void Insert(int tkey){ _Insert(root,tkey); }
    void Delete(int tkey){ _Delete(root,tkey); }
    int Kth(int k){ return _Kth(root,k); }
    int Rank(int tkey){ return _Rank(root,tkey,0); }
    int Pred(int tkey){ return _Pred(root,tkey); }
    int Succ(int tkey){ return _Succ(root,tkey); }
    LL Query(int res){ return _Query(root,res); }
}tp;

int main() {
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; i++) scanf("%d", &d[i]);
    scanf("%d", &num);
    for(int i = 1; i <= num; i++) {
        int x; scanf("%d", &x);
        state[x] |= 1;
    }
    scanf("%d", &num);
    for(int i = 1; i <= num; i++) {
        int x; scanf("%d", &x);
        state[x] |= 2;
    }
    for(int i = 1; i <= n; i++) {
        if(state[i] == 0) tp.Insert(d[i]), cnt++;
        else if(state[i] == 1) a[++a[0]] = d[i];
        else if(state[i] == 2) b[++b[0]] = d[i];
        else c[++c[0]] = d[i];
    }
    sort(a + 1, a + 1 + a[0]);
    sort(b + 1, b + 1 + b[0]);
    sort(c + 1, c + 1 + c[0]);
    for(int i = 1; i <= a[0]; i++)
        suma[i] = suma[i-1] + a[i];
    for(int i = 1; i <= b[0]; i++)
        sumb[i] = sumb[i-1] + b[i];
    for(int i = 1; i <= c[0]; i++)
        sumc[i] = sumc[i-1] + c[i];

    LL ans = INF;
    for(int i = 1; i <= c[0]; i++) tp.Insert(c[i]), cnt++;
    for(int i = 0; i <= c[0]; i++) {
        if(i) tp.Delete(c[i]), cnt--;
        int res1 = max(0, k - i);
        if(a[0] < res1 || b[0] < res1) continue;
        while(a[0] > res1) {
            tp.Insert(a[a[0]]);
            a[0]--; cnt++;
        }
        while(b[0] > res1) {
            tp.Insert(b[b[0]]);
            b[0]--; cnt++;
        }
        if(i + 2 * res1 > m) continue;
        int res2 = m - i - 2 * res1;
        ans = min(ans, sumc[i] + suma[a[0]] + sumb[b[0]] + tp.Query(res2));
    }
    printf("%lld\n", ans == INF ? -1 : ans);
    return 0;
}

/*
*/

原文地址:https://www.cnblogs.com/CJLHY/p/9749690.html

时间: 2024-08-27 00:48:39

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) E - Aquarium decoration 贪心 + 平衡树的相关文章

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains 【树状数组维护区间最大值】

题目传送门:http://codeforces.com/contest/799/problem/C C. Fountains time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Arkady plays Gardenscapes a lot. Arkady wants to build two new fountains. The

【预处理】【分类讨论】Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2) C. Fountains

分几种情况讨论: (1)仅用C或D买两个 ①买两个代价相同的(实际不同)(排个序) ②买两个代价不同的(因为买两个代价相同的情况已经考虑过了,所以此时对于同一个代价,只需要保存美丽度最高的喷泉即可)(预处理b[i],表示代价小于等于i的物品中,美丽度最大的是多少.为了防止重复购买,枚举其中一个,然后另一个只买代价小于其代价的物品.) (2)用C和D各买一个 按这几种情况分类,可以比较好地避免买到同一个喷泉的情况. #include<cstdio> #include<algorithm&g

Playrix Codescapes Cup (Codeforces Round #413, rated, Div. 1 + Div. 2)B. T-shirt buying

传送门 Description A new pack of n t-shirts came to a shop. Each of the t-shirts is characterized by three integers pi, ai and bi, where pi is the price of the i-th t-shirt, ai is front color of the i-th t-shirt and bi is back color of the i-th t-shirt.

Codeforces Round #413, rated, Div. 1 + Div. 2 C. Fountains(贪心 or 树状数组)

http://codeforces.com/contest/799/problem/C 题意: 有n做花园,有人有c个硬币,d个钻石 (2 ≤ n ≤ 100 000, 0 ≤ c, d ≤ 100 000) ,每一个花园用三个维度描述(a,b,c),分别是美丽度,所花钱币个数,钱币种类,当然,钱币之间不能兑换,该人必须要建筑两座花园,如果可以,输出两座花园总的美丽度,否则输出0: 思路: 首先想到分三种情况讨论,两个花园都用硬币,两个花园都用钻石,一个用钻石一个用硬币. 大神的代码真的是很厉害

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching B. Pair of Toys C. Bracket Subsequence D. Array Restoration-区间查询最值(RMQ(ST))

Codeforces Round #504 (rated, Div. 1 + Div. 2, based on VK Cup 2018 Final) A. Single Wildcard Pattern Matching 题意就是匹配字符的题目,打比赛的时候没有看到只有一个" * ",然后就写挫了,被hack了,被hack的点就是判一下只有一个" * ". 1 //A 2 #include<iostream> 3 #include<cstdio&g

Educational Codeforces Round 36 (Rated for Div. 2)

Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree You are given a tree T consisting of n vertices. A number is written on each vertex; the number written on vertex i is ai. Let's denote the function I(x,?y) as the differ

Educational Codeforces Round 36 (Rated for Div. 2) 题解

Educational Codeforces Round 36 (Rated for Div. 2) 题目的质量很不错(不看题解做不出来,笑 Codeforces 920C 题意 给定一个\(1\)到\(n\)组成的数组,只可以交换某些相邻的位置,问是否可以将数组调整为升序的 解题思路 首先如果每个数都能通过交换到它应该到的位置,那么就可以调整为升序的. 但实际上交换是对称的,如果应该在的位置在当前位置前方的数都交换完成,那么整体就是排好序的,因为不可能所有不在相应位置的数都在相应位置的后方.

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes

Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes 题目连接: http://codeforces.com/contest/985/problem/E Description Mishka received a gift of multicolored pencils for his birthday! Unfortunately he lives in a monochrome w

Educational Codeforces Round 55 (Rated for Div. 2)

Educational Codeforces Round 55 (Rated for Div. 2) 链接 A Vasya and Book 傻逼题..注意判边界. #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<set> #include<map> #include<vector> #include<cm