Official
D - 塗り重ねられた壁 / Repainted Wall Editorial
by
D - 塗り重ねられた壁 / Repainted Wall Editorial
by
kyopro_friends
この問題は俗に イベントソート と呼ばれる手法を用いて解くことができます。
問題は次のように読み替えることができます:
高橋君は、 \(N\) 人のユーザーがいる web サービスを運営しています。 \(i\) 番目のユーザは時刻 \(L_i\) にログインし、時刻 \(R_i\) にログアウトしました。 \(K\) 人以上がログインしていた時間の長さの合計を求めてください。
この問題はログインとログアウトの発生を時刻順に処理することで解くことができます。
実装例 (C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
vector<pair<int,int>>events;
for(int i=0; i<n; i++){
int l, r;
cin >> l >> r;
events.push_back({l, 1});
events.push_back({r, -1});
}
sort(events.begin(), events.end());
int ans = 0;
int prev_time = 0;
int crr_count = 0;
for(auto [crr_time, delta]: events){
if(crr_count >= k){
ans += crr_time - prev_time;
}
crr_count += delta;
prev_time = crr_time;
}
cout << ans << endl;
}
実装例 (Python)
N, K = map(int, input().split())
events = []
for _ in range(N):
L, R = map(int, input().split())
events.append((L, 1))
events.append((R, -1))
events.sort()
ans = 0
prev_time = 0
crr_count = 0
for crr_time, delta in events:
if crr_count >= K:
ans += crr_time - prev_time
crr_count += delta
prev_time = crr_time
print(ans)
posted:
last update:
