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; }