mini notes

競技プログラミングの解法メモを残していきます。

AtCoder蟻本 初級編 2-4 データ構造 ①Expedition

CODE THANKS FESTIVAL 2017 C - Factory (300)

C: Factory - CODE THANKS FESTIVAL 2017(Parallel) | AtCoder

概要

N項の数列a,\ bが与えられる。aから数をK回選んでその合計を求めることを考える。ただし、各a_{i}は一度選ばれるごとにb_{i}が加算されるものとする。
数をK回選んだ合計の最小値を求めよ。

制約

1 \leq N \leq 10^5
1 \leq K \leq 10^5
1 \leq a_{i} \leq 10^9
0 \leq b_{i} \leq 10^9

方針

priority queueを使う。
最小値a_{i}をpriority queueから取り出してansに加算し、a_{i} + b_{i}をpriority queueに入れる。これを繰り返す。

解答

Submission #4081765 - CODE THANKS FESTIVAL 2017(Parallel) | AtCoder

#include <bits/stdc++.h>
 
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define rep(i,n) FOR(i,0,n)
#define RFOR(i,a,b) for(int i=(a)-1;i>=(b);i--)
#define rrep(i,n) RFOR(i,n,0)
#define fi first
#define se second
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> pll;
 
int main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);
 
	ll N, K;
	cin >> N >> K;
 
	ll a[N], b[N];
	rep(i, N) cin >> a[i] >> b[i];
 
	priority_queue<pll, vector<pll>, greater<pll> > que;
	rep(i, N) que.push((pll){a[i], i});
 
	ll ans = 0;
	rep(i, K){
		pll x = que.top();
		que.pop();
		ans += x.fi;
		que.push((pll){x.fi + b[x.se], x.se});
	}
 
	cout << ans << endl;
}