Official
C - 山の見える展望台 / Observatory with a Mountain View Editorial
by
C - 山の見える展望台 / Observatory with a Mountain View Editorial
by
kyopro_friends
Editorial for printing
この問題は累積和を用いて解くことができます。
山の番号は問題に影響しないため、標高の降順にソートしてよいです。
その後、美しさの累積和を求めておきます。
このとき、各調査において求めるものは、「先頭からいくつかの山の美しさの和」であるため、標高の配列を二分探索し何番目の山までが標高 \(L_j\) 以上であるかを求め、美しさの累積和の配列を参照することで求めることができます。
よって全体で \(O((N+Q)\log N)\) でこの問題を解くことができます。
以下の実装例では、山を標高の昇順にソートし、「標高が低い山の美しさを全体から引く」として答えを求めています。
実装例 (C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, q;
cin >> n >> q;
vector<pair<int,int>>yp(n);
for(int i=0; i<n; i++) cin >> yp[i].first >> yp[i].second;
sort(yp.begin(),yp.end());
// 累積和
vector<long long>s({0});
for(int i=0; i<n; i++){
s.push_back(s.back() + yp[i].second);
}
for(int k=0; k<q; k++){
int l;
cin >> l;
int i = lower_bound(yp.begin(), yp.end(), make_pair(l, 0)) - yp.begin();
cout << s.back() - s[i] << endl;
}
}
実装例 (Python)
import bisect
N, Q = map(int, input().split())
YP = []
for _ in range(N):
Y, P = map(int,input().split())
YP.append((Y, P))
YP.sort()
# 累積和
S=[0]
for _, p in YP:
S.append(S[-1]+p)
for _ in range(Q):
L = int(input())
i = bisect.bisect_left(YP, (L, 0))
print(S[-1] - S[i])
posted:
last update:
