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.
The first line contains two integers nn and kk (1≤n≤105,0≤k≤min(n−1,10))(1≤n≤105,0≤k≤min(n−1,10)) — the number of knights and the number kk from the statement.
The second line contains nn integers p1,p2,…,pnp1,p2,…,pn (1≤pi≤109)(1≤pi≤109) — powers of the knights. All pipi are distinct.
The third line contains nn integers c1,c2,…,cnc1,c2,…,cn (0≤ci≤109)(0≤ci≤109) — the number of coins each knight has.
Print nn integers — the maximum number of coins each knight can have it only he kills other knights.
4 2 4 5 9 7 1 2 11 33
1 3 46 36
5 1 1 2 3 4 5 1 2 3 4 5
1 3 5 7 9
1 0 2 3
3
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.
#include<algorithm>
#include<iostream>
#include<string>
#include<map>//int dx[4]={0,0,-1,1};int dy[4]={-1,1,0,0};
#include<set>//int gcd(int a,int b){return b?gcd(b,a%b):a;}
#include<vector>
#include<cmath>
#include<queue>
#include<string.h>
#include<stdlib.h>
#include<cstdio>
#define maxn 100003
using namespace std;
struct node
{
int coin,index,pow;
node() {}
};
node seq[maxn];
/*
题意:给定n个数和指标k;
对每个数,求在pow比他小的集合中选出至多k个人使得那k个人金币数
和连通他自己的数量最大,,
n对每个人都这样处理,最后得到的答案是n个数的序列.
这题一直想者用dp处理无果。。。
按力量排序是常规操作,,
对枚举到的位置i,在前面i个人当中,对于这个集合要维护一个从小到大的序列,
参照大佬的代码想到了优先队列,这真是好招。。。
利用优先队列维护的最小堆,可以很方便的进行添加和删除。
当队列的大小超过k时,要进行删除操作。此时维护的s变量要减去退出的数。
*/
bool cmp(node x,node y)
{
return x.pow<y.pow;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++) scanf("%d",&seq[i].pow);
for(int i=0;i<n;i++) scanf("%d",&seq[i].coin);
for(int i=0;i<n;i++) seq[i].index=i;
sort(seq,seq+n,cmp);
priority_queue<int> pq;
long long ans[maxn];
memset(ans,0,sizeof(ans));
long long s=0;
for(int i=0;i<n;i++)
{
s+=seq[i].coin;
pq.push(-seq[i].coin);
ans[seq[i].index]=s;
while(pq.size()>m)
{
s+=pq.top();
pq.pop();
}
}
for(int i=0;i<n;i++) printf("%d ",ans[i]);
puts("");
return 0;
}