zoukankan      html  css  js  c++  java
  • CF994B Knights of a Polygonal Table 第一道 贪心 set/multiset的用法

    Knights of a Polygonal Table
    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    Unlike Knights of a Round Table, Knights of a Polygonal Table deprived of nobility and happy to kill each other. But each knight has some power and a knight can kill another knight if and only if his power is greater than the power of victim. However, even such a knight will torment his conscience, so he can kill no more than kk other knights. Also, each knight has some number of coins. After a kill, a knight can pick up all victim's coins.

    Now each knight ponders: how many coins he can have if only he kills other knights?

    You should answer this question for each knight.

    Input

    The first line contains two integers nn and k(1n105,0kmin(n1,10))(1≤n≤105,0≤k≤min(n−1,10)) — the number of knights and the number kkfrom the statement.

    The second line contains nn integers p1,p2,,pnp1,p2,…,pn (1pi109)(1≤pi≤109) — powers of the knights. All pipi are distinct.

    The third line contains nn integers c1,c2,,cnc1,c2,…,cn (0ci109)(0≤ci≤109) — the number of coins each knight has.

    Output

    Print nn integers — the maximum number of coins each knight can have it only he kills other knights.

    Examples
    input
    Copy
    4 2
    4 5 9 7
    1 2 11 33
    output
    Copy
    1 3 46 36 
    input
    Copy
    5 1
    1 2 3 4 5
    1 2 3 4 5
    output
    Copy
    1 3 5 7 9 
    input
    Copy
    1 0
    2
    3
    output
    Copy
    3 
    Note

    Consider the first example.

    • The first knight is the weakest, so he can't kill anyone. That leaves him with the only coin he initially has.
    • The second knight can kill the first knight and add his coin to his own two.
    • The third knight is the strongest, but he can't kill more than k=2k=2 other knights. It is optimal to kill the second and the fourth knights:2+11+33=462+11+33=46.
    • The fourth knight should kill the first and the second knights: 33+1+2=3633+1+2=36.

    In the second example the first knight can't kill anyone, while all the others should kill the one with the index less by one than their own.

    In the third example there is only one knight, so he can't kill anyone.

    题目给出n个knight,每个knight最多可以杀死k个其余的knight,第一行是每个knight的攻击力,第二行是每个knight的价值。

    每个knight杀死其他knight之后可以增加被杀者的价值。

    问每个knight最多可以拥有的价值。

    按每个knight的攻击力排序,这样我们可以按攻击力从小到大遍历,计算时我们先加上所有的knight价值,用一个multiset保存下来(自动从小到大顺序保存可重复的所有值)。当multiset中的个数大于k时,我就减去第一个(最小的值),这样我们可以保证每个knight杀死了他所能杀死的所有knight中价值最大的k个。

    附上multiset的用法:

    3.1 构造、拷贝、析构

    操作

    效果

    set c

    产生一个空的set/multiset,不含任何元素

    set c(op)

    以op为排序准则,产生一个空的set/multiset

    set c1(c2)

    产生某个set/multiset的副本,所有元素都被拷贝

    set c(beg,end)

    以区间[beg,end)内的所有元素产生一个set/multiset

    set c(beg,end, op)

    以op为排序准则,区间[beg,end)内的元素产生一个set/multiset

    c.~set()

    销毁所有元素,释放内存

    set<Elem>

    产生一个set,以(operator <)为排序准则

    set<Elem,0p>

    产生一个set,以op为排序准则

    3.2 非变动性操作

    操作

    效果

    c.size()

    返回当前的元素数量

    c.empty ()

    判断大小是否为零,等同于0 == size(),效率更高

    c.max_size()

    返回能容纳的元素最大数量

    c1 == c2

    判断c1是否等于c2

    c1 != c2

    判断c1是否不等于c2(等同于!(c1==c2))

    c1 < c2

    判断c1是否小于c2

    c1 > c2

    判断c1是否大于c2

    c1 <= c2

    判断c1是否小于等于c2(等同于!(c2<c1))

    c1 >= c2

    判断c1是否大于等于c2 (等同于!(c1<c2))

    3.3 特殊的搜寻函数

      sets和multisets在元素快速搜寻方面做了优化设计,提供了特殊的搜寻函数,所以应优先使用这些搜寻函数,可获得对数复杂度,而非STL的线性复杂度。比如在1000个元素搜寻,对数复杂度平均十次,而线性复杂度平均需要500次。

    操作

    效果

    count (elem)

    返回元素值为elem的个数

    find(elem)

    返回元素值为elem的第一个元素,如果没有返回end()

    lower _bound(elem)

    返回元素值为elem的第一个可安插位置,也就是元素值 >= elem的第一个元素位置

    upper _bound (elem)

    返回元素值为elem的最后一个可安插位置,也就是元素值 > elem 的第一个元素位置

    equal_range (elem)

    返回elem可安插的第一个位置和最后一个位置,也就是元素值==elem的区间

    3.4 赋值

    操作

    效果

    c1 = c2

    将c2的元素全部给c1

    c1.swap(c2)

    将c1和c2 的元素互换

    swap(c1,c2)

    同上,全局函数

    3.5 迭代器相关函数

      sets和multisets的迭代器是双向迭代器,对迭代器操作而言,所有的元素都被视为常数,可以确保你不会人为改变元素值,从而打乱既定顺序,所以无法调用变动性算法,如remove()。

    操作

    效果

    c.begin()

    返回一个随机存取迭代器,指向第一个元素

    c.end()

    返回一个随机存取迭代器,指向最后一个元素的下一个位置

    c.rbegin()

    返回一个逆向迭代器,指向逆向迭代的第一个元素

    c.rend()

    返回一个逆向迭代器,指向逆向迭代的最后一个元素的下一个位置

    3.6 安插和删除元素

      必须保证参数有效,迭代器必须指向有效位置,序列起点不能位于终点之后,不能从空容器删除元素。

    操作

    效果

    c.insert(elem)

    插入一个elem副本,返回新元素位置,无论插入成功与否。

    c.insert(pos, elem)

    安插一个elem元素副本,返回新元素位置,pos为收索起点,提升插入速度。

    c.insert(beg,end)

    将区间[beg,end)所有的元素安插到c,无返回值。

    c.erase(elem)

    删除与elem相等的所有元素,返回被移除的元素个数。

    c.erase(pos)

    移除迭代器pos所指位置元素,无返回值。

    c.erase(beg,end)

    移除区间[beg,end)所有元素,无返回值。

    c.clear()

    移除所有元素,将容器清空

    #include <map>
    #include <set>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <vector>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define debug(a) cout << #a << " " << a << endl;
    using namespace std;
    const int maxn = 1e5 + 10;
    typedef long long ll;
    struct node {
        ll power, value, index;
    };
    bool cmp( node p, node q ) {
        return p.power < q.power;
    }
    node a[maxn];
    ll num[maxn];
    int main(){
        std::ios::sync_with_stdio(false);
        ll n, k;
        while( cin >> n >> k ) {
            memset( num, 0, sizeof(num) );
            for( ll i = 0; i < n; i ++ ) {
                cin >> a[i].power;
                a[i].index = i;
            }
            for( ll i = 0; i < n; i ++ ) {
                cin >> a[i].value;
            }
            sort( a, a + n, cmp );
            ll sum = 0;
            multiset<ll> s;
            for( ll i = 0; i < n; i ++ ) {
                num[a[i].index] = sum + a[i].value;
                sum += a[i].value;
                s.insert(a[i].value);
                while( s.size() > k ) {
                    sum -= *s.begin();
                    s.erase(s.begin());
                }
            }
            for( ll i = 0; i < n; i ++ ) {
                if( i == n - 1 ) {
                    cout << num[i] << endl;
                } else {
                    cout << num[i] << " ";
                }
            }
        }
        return 0;
    }
    彼时当年少,莫负好时光。
  • 相关阅读:
    ubuntn16.04指令
    [Array]283. Move Zeroes
    spring框架
    Redis服务器搭建/配置/及Jedis客户端的使用方法
    [Java Performance] 数据库性能最佳实践
    iOS 序列化和反序列化
    SSH 获取GET/POST参数
    MAC中安卓开发环境的下载
    MAC OS下使用OpenSSL生成私钥和公钥的方法
    如何使用TestFlight进行Beta测试
  • 原文地址:https://www.cnblogs.com/l609929321/p/9204688.html
Copyright © 2011-2022 走看看