1+ <!-- 以下は、**PHP** を用いて「配列 A の中に X 未満の要素がいくつあるか」を効率的に求めるプログラムです。
2+ 処理時間とメモリ使用量を意識し、**ソート + 二分探索(lower\_bound)** を用います。
3+
4+ ---
5+
6+ ## ✅ アルゴリズム概要
7+
8+ 1. **配列 A を昇順ソート**:`O(N log N)`
9+ 2. 各クエリ `X` に対して **二分探索**(`X` 未満の要素数)を求める:`O(Q log N)`
10+ 3. **標準入力**:`fgets()` + `explode()` を使用
11+ 4. **型注釈**:PHP 8.2 に準拠(`array<int>` や `int` 型)
12+
13+ ---
14+
15+ ## ✅ PHP 実装(PHP 8.2, 型付き)
16+
17+ ```php -->
18+ <?php
19+
20+ declare (strict_types=1 );
21+
22+ // 二分探索: $arr の中で $target より小さい要素の個数を返す
23+ function lower_bound (array $ arr , int $ target ): int {
24+ $ left = 0 ;
25+ $ right = count ($ arr );
26+ while ($ left < $ right ) {
27+ $ mid = intdiv ($ left + $ right , 2 );
28+ if ($ arr [$ mid ] < $ target ) {
29+ $ left = $ mid + 1 ;
30+ } else {
31+ $ right = $ mid ;
32+ }
33+ }
34+ return $ left ;
35+ }
36+
37+ // 入力読み込み(高速)
38+ $ stdin = fopen ('php://stdin ' , 'r ' );
39+ $ N = (int )fgets ($ stdin );
40+ $ A = array_map ('intval ' , explode (' ' , trim (fgets ($ stdin ))));
41+ sort ($ A ); // 昇順ソート
42+
43+ $ Q = (int )fgets ($ stdin );
44+
45+ // 結果配列
46+ $ results = [];
47+
48+ for ($ i = 0 ; $ i < $ Q ; $ i ++) {
49+ $ X = (int )fgets ($ stdin );
50+ $ count = lower_bound ($ A , $ X );
51+ $ results [] = $ count ;
52+ }
53+
54+ // 出力(高速)
55+ echo implode ("\n" , $ results ) . "\n" ;
56+ // ```
57+
58+ // ---
59+
60+ // ## ✅ 入力例の確認
61+
62+ // ### 入力:
63+
64+ // ```
65+ // 5
66+ // 1 3 3 3 1
67+ // 2
68+ // 4
69+ // 3
70+ // ```
71+
72+ // ### 出力:
73+
74+ // ```
75+ // 5
76+ // 2
77+ // ```
78+
79+ // ---
80+
81+ // ## ✅ 処理時間・メモリの見積もり
82+
83+ // ### 時間計算量
84+
85+ // | 処理項目 | 計算量 |
86+ // | --------- | ---------------------------------- |
87+ // | 配列 A のソート | `O(N log N)` |
88+ // | 各クエリの探索 | `O(Q log N)` |
89+ // | 合計 | `O(N log N + Q log N)`(≒ 2×10⁶ 以内) |
90+
91+ // ✅ 最大入力 (`N = Q = 10^5`) に対しても **十分高速(1 秒以内)**
92+
93+ // ---
94+
95+ // ### メモリ使用量(推定)
96+
97+ // * `A`: 約 `100,000 × 4B = 約 400 KB`
98+ // * `X` クエリ: 約 `400 KB`
99+ // * `$results`: 最大 `400 KB`
100+ // * その他合わせて:約 **1〜2 MB**
101+
102+ // ✅ 1024 MiB 制限に **十分収まる**
103+
104+ // ---
105+
106+ // ## ✅ 解法まとめ
107+
108+ // | 特徴 | 内容 |
109+ // | ----- | ------------------------------- |
110+ // | ソート | `sort($A)` で事前に準備(昇順) |
111+ // | クエリ応答 | `lower_bound()` で `X` 未満の要素数を返す |
112+ // | 時間効率 | `O(log N)` × Q で高速 |
113+ // | メモリ効率 | 数MB程度で非常に良好 |
114+
115+ // ---
0 commit comments