CF994B Knights of a Polygonal Table 第一道 贪心 set/multiset的用法

Posted 九月旧约

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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(n?1,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;
}

 

以上是关于CF994B Knights of a Polygonal Table 第一道 贪心 set/multiset的用法的主要内容,如果未能解决你的问题,请参考以下文章

Knights of a Polygonal Table(骑士的多角桌)

POJ 2942Knights of the Round Table(二分图判定+双连通分量)

Codeforces 994B. Knights of a Polygonal Table

UvaLive3523 Knights of the Round Table(点双联通分量+二分图染色)

CF1067C Knights 构造

[Usaco2005 Dec]Knights of Ni 骑士