#include #include #include #include using namespace std; /** * Tối ưu hóa: * 1. Dùng unordered_map để truy cập O(1). * 2. Nhóm các vật phẩm có cùng w_i để giảm số lần tính ước. * 3. Tính toán trực tiếp trong lúc tìm ước. */ int main() { ios::sync_with_stdio(false); cin.tie(NULL); int N; long long W; if (!(cin >> N >> W)) return 0; unordered_map weights; for (int i = 0; i < N; ++i) { int w, v; cin >> w >> v; if (w >= W) { weights[w] += v; } } // gcd_sums lưu: [giá trị GCD g] -> [tổng giá trị v thu được] unordered_map gcd_sums; gcd_sums.reserve(100000); // Giảm việc rehash for (auto const& [w, v] : weights) { // Tìm ước của w trong O(sqrt(w)) for (int d = 1; d * d <= w; ++d) { if (w % d == 0) { if (d >= W) { gcd_sums[d] += v; } int other = w / d; if (other != d && other >= W) { gcd_sums[other] += v; } } } } long long max_ans = 0; for (auto const& [g, total_v] : gcd_sums) { if (total_v > max_ans) { max_ans = total_v; } } cout << max_ans << endl; return 0; }