K - 奇妙な等式/Strange Equation 解説
by
sounansya
\(\max(A_i,B_j - C_i) = D_j + E_i\) の両辺から \(A_i\) を引くと \(\max(0,B_j - (C_i+A_i)) = D_j + E_i-A_i\) となります。したがって、 \(C_i\) に \(A_i\) を足し、 \(E_i\) から \(A_i\) を引くことで \(A_i=0\) の場合に帰着させることができます。以降は \(A_i= 0\) の場合を考えます。
条件式は \(\max(0,B_j - C_i) = D_j + E_i\) となります。
1. \(B_j \le C_i\) のとき
条件式は \(E_i=-D_j\) となります。したがって、 \(j=1,2,\ldots,N\) に対して \(-D_j\) を鍵として \(B_j\) の値のリストを持つ map を用意し、 \(i=1,2,\ldots,N\) に対し \(E_i\) を鍵として持つリストに対し \(C_i\) 以下の要素がいくつあるかを求めれば良いです。
2. \(B_j > C_i\) のとき
条件式は \(C_i+E_i=B_j-D_j\) となります。したがって、 \(j=1,2,\ldots,N\) に対して \(B_j-D_j\) を鍵として \(B_j\) の値のリストを持つ map を用意し、 \(i=1,2,\ldots,N\) に対し \(E_i\) を鍵として持つリストに対し \(C_i\) より大きい要素がいくつあるかを求めれば良いです。
以上の 1. と 2. で求めた答えの和がこの問題の答えとなります。
以上を適切に実装することでこの問題を解くことができます。
実装例(C++)
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<int> a(n), b(n), c(n), d(n), e(n);
for (int &i : a) cin >> i;
for (int &i : b) cin >> i;
for (int &i : c) cin >> i;
for (int &i : d) cin >> i;
for (int &i : e) cin >> i;
for (int i = 0; i < n; i++) {
c[i] += a[i];
e[i] -= a[i];
}
unordered_map<int, vector<int>> mp1, mp2;
for (int i = 0; i < n; i++) {
mp1[-d[i]].push_back(b[i]);
mp2[b[i] - d[i]].push_back(b[i]);
}
for (auto &[_, v] : mp1)
sort(v.begin(), v.end());
for (auto &[_, v] : mp2)
sort(v.begin(), v.end());
for (int i = 0, y; i < n; i++) {
int ans = 0;
y = e[i];
ans += lower_bound(mp1[y].begin(), mp1[y].end(), c[i]) - mp1[y].begin();
y = c[i] + e[i];
ans += mp2[y].end() - lower_bound(mp2[y].begin(), mp2[y].end(), c[i]);
cout << ans << " \n"[i == n - 1];
}
}
投稿日時:
最終更新:
