-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
440 lines (440 loc) · 182 KB
/
search.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
431
432
433
434
435
436
437
438
439
440
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 B</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-B/</url>
<content><![CDATA[<h1 id="Problem-B-Binomial"><a href="#Problem-B-Binomial" class="headerlink" title="Problem B. Binomial"></a>Problem B. Binomial</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给定序列 $a_1,a_2,\dots, a_n$,问有多少对 $(a_i,a_j)$ 满足 $\binom{a_i}{a_j} \bmod 2 = 1$ 。有 $z$ 组测试数据。</p>
<p>$1 \leq z \leq 10$</p>
<p>$1 \leq n \leq 10^6$, $1 \leq a_i \leq 10^6$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>Lucas 定理有一个经典的推论:</p>
<script type="math/tex; mode=display">
\binom{a_i}{a_j} \bmod 2 = 1 \leftrightarrow a_i \& a_j = a_j</script><p>因此,问题转化为求</p>
<script type="math/tex; mode=display">
\sum_{i=1}^{n} \sum_{j=1}^{n} [a_i \& a_j = a_j]</script><p>记 $m = \lceil \log (\max a_i) \rceil$。显然,暴力枚举可以做到 $O(n^2)$ 的复杂度。优化一下,枚举子集可以做到 $O(3^m)$ 的复杂度。但是要通过这题还是不够。clp012345 说可以 <a href="https://codeforces.com/blog/entry/45223" target="_blank" rel="noopener">Sum over Submask DP</a> 做到 $O(m2^m)$,于是 triple_a 就现学现用写了一个。</p>
<p>这个算法本身就不讲了,可以看上面链接的文章。在国内,这个算法一般被称作快速莫比乌斯变换 (FMT) 或者子集和变换,英文不好的话也可以搜这两个词,但感觉其实大部分文章都写得对新手不是很友好。个人觉得可以看<a href="http://blog.leanote.com/post/rockdu/TX20" target="_blank" rel="noopener">这篇</a>,我觉得下面这张插图真的把 FMT 解释得非常清楚。</p>
<p><img src="https://leanote.com/api/file/getImage?fileId=5bf20918ab64411b7b0012e2" alt="一个栗子"></p>
<p>是的,FMT 和 FWT 相关的题代码基本都不长,但是,我觉得确实不太好懂。</p>
<h2 id="Code-By-triple-a"><a href="#Code-By-triple-a" class="headerlink" title="Code (By triple_a)"></a>Code (By triple_a)</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><bits/stdc++.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> int long long</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> maxn=(<span class="number">1</span><<<span class="number">20</span>);</span><br><span class="line"><span class="keyword">int</span> a[maxn],b[maxn],F[maxn],n,t;</span><br><span class="line"><span class="function"><span class="keyword">signed</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> ios::sync_with_stdio(<span class="literal">false</span>);</span><br><span class="line"> <span class="built_in">cin</span>.tie(<span class="number">0</span>), <span class="built_in">cout</span>.tie(<span class="number">0</span>);</span><br><span class="line"> <span class="built_in">cin</span>>>t;</span><br><span class="line"> <span class="keyword">while</span> (t--){</span><br><span class="line"> <span class="built_in">cin</span>>>n;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<(<span class="number">1</span><<<span class="number">20</span>);++i) b[i]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<n;++i) <span class="built_in">cin</span>>>a[i], b[a[i]]++;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i<(<span class="number">1</span><<<span class="number">20</span>); ++i)</span><br><span class="line"> F[i] = b[i];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>;i < <span class="number">20</span>; ++i) <span class="keyword">for</span>(<span class="keyword">int</span> mask = <span class="number">0</span>; mask < (<span class="number">1</span><<<span class="number">20</span>); ++mask){</span><br><span class="line"> <span class="keyword">if</span>(mask & (<span class="number">1</span><<i))</span><br><span class="line"> F[mask] += F[mask^(<span class="number">1</span><<i)];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> res=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<(<span class="number">1</span><<<span class="number">20</span>);++i){</span><br><span class="line"> res+=b[i]*F[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">cout</span><<res<<<span class="built_in">endl</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>
]]></content>
<categories>
<category>数论</category>
<category>FMT/FWT</category>
</categories>
<tags>
<tag>Lucas定理</tag>
<tag>FMT/FWT</tag>
</tags>
</entry>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 A</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-A/</url>
<content><![CDATA[<h1 id="Problem-A-Bags-of-Candies"><a href="#Problem-A-Bags-of-Candies" class="headerlink" title="Problem A. Bags of Candies"></a>Problem A. Bags of Candies</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>把 $A = {1,2,\dots,n}$ 分成尽可能多对,使得每一对的两个数都不互质,问 $n$ 减去配对次数的值。有 $z$ 组测试数据。</p>
<p>$1 \leq z \leq 5$</p>
<p>$2 \leq n \leq 10^{11}$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>半场的时候动这个题的队伍只有个位数。可能大家都觉得有别的题可做,不像我这么菜别的都不会就来瞎猜结论了啊。于是结论就是,将 $1$ 和大于 $\lfloor \frac n2 \rfloor$ 的质数从 $A$ 里删掉,剩下的集合 $A’$ 一定是可以匹配满的,所以配对次数就是 $\frac {|A’|}2$。</p>
<p><del>赛中是瞎猜的,</del>这里给一个简单证明。</p>
<p>将 $A’$ 的所有元素按最大质因子 $d$ 分组,那么每组都可以表示成 $A_d = {d,2d,\dots,\lfloor \frac nd \rfloor d}$ 的形式(注意并不一定 $|A_d|=\lfloor \frac nd \rfloor$,比如 $77 \notin A_7$),显然组内的数都是不互质的。</p>
<p>如果 $|A_d|$ 是偶数,直接令组内的数任意两两配对;如果 $|A_d|$ 是奇数,则除了 $2d$ 以外任意两两配对。所有组都作完以上匹配之后,剩下的数都是 $2$ 的倍数,所以也都不互质,也可以任意两两配对。注意到对于任意 $d$ 有 $|A_d| \geq 2$ 即不存在 $|A_d| = 1$,所以最后剩下的数显然至多只有一个。</p>
<p>至此,剩下的任务就是筛 $10^{11}$ 以内的质数个数。这东西听上去很不可做,又或者是某种奥妙重重的高级筛法,但 clp012345 说有一种叫作 <a href="https://tanakarino.cn/2020/06/02/Meissel-Lehmer算法/">Meissel-Lehmer</a> 的神棍算法可以 $O(n^\frac 23)$ 求这个东西,于是我<del>临时找了个板子复制粘贴</del>交了两发过了(?)。赛后看官方题解居然是分段打表,太暴力了……</p>
<p>关于这个算法的更多内容可以看上面的链接。</p>
<h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sstream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iomanip></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> all(v) (v).begin(), (v).end()</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> unq(v) (v).erase(unique(all(v)), (v).end())</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ii int, int</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> li int, int</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ll2 ll, ll</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> vec vector</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pii pair <span class="meta-string"><int, int></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pli pair <span class="meta-string"><ll, int></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pll2 pair <span class="meta-string"><ll, ll></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> mp make_pair</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pb push_back</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> fi first</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> se second</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MULTI int T; cin >> T; while(T--)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> sqr(x) ((x) * (x))</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> test cerr << <span class="meta-string">'!'</span> << endl;</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main0</span> <span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">ifndef</span> ONLINE_JUDGE</span></span><br><span class="line"> freopen(<span class="string">"C:\\Users\\98497\\Desktop\\code\\file.in"</span>, <span class="string">"r"</span>, <span class="built_in">stdin</span>);</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"> ios::sync_with_stdio(<span class="literal">false</span>);</span><br><span class="line"> <span class="keyword">clock_t</span> start, <span class="built_in">end</span>;</span><br><span class="line"> <span class="comment">// start = clock();</span></span><br><span class="line"> main0();</span><br><span class="line"> <span class="comment">// end = clock();</span></span><br><span class="line"> <span class="comment">// cout << (end - start) << endl;</span></span><br><span class="line"> <span class="meta">#<span class="meta-keyword">ifndef</span> ONLINE_JUDGE</span></span><br><span class="line"> fclose(<span class="built_in">stdin</span>);</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">endif</span></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><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dx[<span class="number">8</span>] = {<span class="number">0</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">-1</span>};</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dy[<span class="number">8</span>] = {<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">-1</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">-1</span>, <span class="number">1</span>};</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> INF = <span class="number">0x3f3f3f3f</span>;</span><br><span class="line"><span class="keyword">const</span> ll INFF = <span class="number">0x3f3f3f3f3f3f3f3f</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod = <span class="number">998244353</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">double</span> eps = <span class="number">1e-6</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">double</span> Pi = <span class="built_in">acos</span>(<span class="number">-1.0</span>);</span><br><span class="line"> </span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">5e6</span> + <span class="number">2</span>;<span class="comment">//通过知道前面的n^1/3的=质数可以推断后面n^2/3的质数所以可以适当减小</span></span><br><span class="line"><span class="keyword">bool</span> np[N];</span><br><span class="line"><span class="keyword">int</span> prime[N], pi[N];</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">getprime</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> cnt = <span class="number">0</span>;</span><br><span class="line"> np[<span class="number">0</span>] = np[<span class="number">1</span>] = <span class="literal">true</span>;</span><br><span class="line"> pi[<span class="number">0</span>] = pi[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">2</span>; i < N; ++i)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(!np[i]) prime[++cnt] = i;</span><br><span class="line"> pi[i] = cnt;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">1</span>; j <= cnt && i * prime[j] < N; ++j)</span><br><span class="line"> {</span><br><span class="line"> np[i * prime[j]] = <span class="literal">true</span>;</span><br><span class="line"> <span class="keyword">if</span>(i % prime[j] == <span class="number">0</span>) <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> cnt;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> M = <span class="number">7</span>;<span class="comment">//为了减小内存可以不过是质数</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> PM = <span class="number">2</span> * <span class="number">3</span> * <span class="number">5</span> * <span class="number">7</span> * <span class="number">11</span> * <span class="number">13</span> * <span class="number">17</span>;<span class="comment">//为了减小内存可以不过要按质数减小如去掉17</span></span><br><span class="line"><span class="keyword">int</span> phi[PM + <span class="number">1</span>][M + <span class="number">1</span>], sz[M + <span class="number">1</span>];</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">init</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> getprime();</span><br><span class="line"> sz[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i <= PM; ++i) phi[i][<span class="number">0</span>] = i;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i <= M; ++i)</span><br><span class="line"> {</span><br><span class="line"> sz[i] = prime[i] * sz[i - <span class="number">1</span>];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">1</span>; j <= PM; ++j) phi[j][i] = phi[j][i - <span class="number">1</span>] - phi[j / prime[i]][i - <span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">sqrt2</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> ll r = (ll)<span class="built_in">sqrt</span>(x - <span class="number">0.1</span>);</span><br><span class="line"> <span class="keyword">while</span>(r * r <= x) ++r;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">int</span>(r - <span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">sqrt3</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> ll r = (ll)cbrt(x - <span class="number">0.1</span>);</span><br><span class="line"> <span class="keyword">while</span>(r * r * r <= x) ++r;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">int</span>(r - <span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">getphi</span><span class="params">(ll x, <span class="keyword">int</span> s)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(s == <span class="number">0</span>) <span class="keyword">return</span> x;</span><br><span class="line"> <span class="keyword">if</span>(s <= M) <span class="keyword">return</span> phi[x % sz[s]][s] + (x / sz[s]) * phi[sz[s]][s];</span><br><span class="line"> <span class="keyword">if</span>(x <= prime[s]*prime[s]) <span class="keyword">return</span> pi[x] - s + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(x <= prime[s]*prime[s]*prime[s] && x < N)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> s2x = pi[sqrt2(x)];</span><br><span class="line"> ll ans = pi[x] - (s2x + s - <span class="number">2</span>) * (s2x - s + <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = s + <span class="number">1</span>; i <= s2x; ++i) ans += pi[x / prime[i]];</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> getphi(x, s - <span class="number">1</span>) - getphi(x / prime[s], s - <span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">getpi</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(x < N) <span class="keyword">return</span> pi[x];</span><br><span class="line"> ll ans = getphi(x, pi[sqrt3(x)]) + pi[sqrt3(x)] - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = pi[sqrt3(x)] + <span class="number">1</span>, ed = pi[sqrt2(x)]; i <= ed; ++i) ans -= getpi(x / prime[i]) - i + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">lehmer_pi</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(x < N) <span class="keyword">return</span> pi[x];</span><br><span class="line"> <span class="keyword">int</span> a = (<span class="keyword">int</span>)lehmer_pi(sqrt2(sqrt2(x)));</span><br><span class="line"> <span class="keyword">int</span> b = (<span class="keyword">int</span>)lehmer_pi(sqrt2(x));</span><br><span class="line"> <span class="keyword">int</span> c = (<span class="keyword">int</span>)lehmer_pi(sqrt3(x));</span><br><span class="line"> ll sum = getphi(x, a) +(ll)(b + a - <span class="number">2</span>) * (b - a + <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = a + <span class="number">1</span>; i <= b; i++)</span><br><span class="line"> {</span><br><span class="line"> ll w = x / prime[i];</span><br><span class="line"> sum -= lehmer_pi(w);</span><br><span class="line"> <span class="keyword">if</span> (i > c) <span class="keyword">continue</span>;</span><br><span class="line"> ll lim = lehmer_pi(sqrt2(w));</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = i; j <= lim; j++) sum -= lehmer_pi(w / prime[j]) - (j - <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> sum;</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main0</span> <span class="params">()</span> </span>{</span><br><span class="line"> init();</span><br><span class="line"> MULTI {</span><br><span class="line"> ll n;</span><br><span class="line"> <span class="built_in">cin</span> >> n;</span><br><span class="line"> <span class="comment">//cout << lehmer_pi(n) << ' ' << lehmer_pi(n / 2) << endl;</span></span><br><span class="line"> ll k = lehmer_pi(n) - lehmer_pi(n / <span class="number">2</span>) + <span class="number">1</span>;</span><br><span class="line"> <span class="built_in">cout</span> << n - (n - k) / <span class="number">2</span> << <span class="built_in">endl</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数论</category>
<category>整除与同余</category>
</categories>
<tags>
<tag>Meissel-Lehmer算法</tag>
</tags>
</entry>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 F</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-F/</url>
<content><![CDATA[<h1 id="Problem-F-The-Halfwitters"><a href="#Problem-F-The-Halfwitters" class="headerlink" title="Problem F. The Halfwitters"></a>Problem F. The Halfwitters</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给定长度 $n$,给定 $a, b, c$,给 $d$ 次询问。每次询问是一个长度为 $n$ 的排列,你可以对这个票列做三种操作:</p>
<ol>
<li><p>花费 $a$ 代价,交换相邻的两个数;</p>
</li>
<li><p>花费 $b$ 代价,翻转这个排列;</p>
</li>
<li><p>花费 $c$ 代价,shuffle 这个排列。</p>
</li>
</ol>
<p>对于每次询问,你需要求出,在最优的操作策略下,把排列排成升序所需的最小期望代价。有 $z$ 组测试数据。</p>
<p>$2 \leq n \leq 16$, $1 \leq a, b, c \leq 1000$, $1 \leq d \leq 10000$</p>
<p> $\sum d \leq 10^5$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>考虑只有第一种操作,我们不难发现,总代价只跟逆序对数 $inv$ 有关。</p>
<script type="math/tex; mode=display">
ans_{1}(inv) = inv \cdot a</script><p>考虑加上第二种操作,我们不难发现,先翻转一下再只进行以上操作可能会更快!</p>
<script type="math/tex; mode=display">
ans_{12}(inv) = \min(ans_{1}(inv), b + (\frac{n(n-1)}{2} - inv) \cdot a)</script><p>考虑加上第三种操作,我们不难发现,先 shuffle 一下再只进行以上操作可能会更快!我们令 shuffle 后代价的期望是 $x$。</p>
<script type="math/tex; mode=display">
ans_{123} = \min(ans_{12}(inv), x + c)</script><p>那么,怎么求 $x$ 呢?记逆序对数为 $inv$ 的排列有 $L_{inv}$ 个,如果我们只能进行一次 shuffle 操作,那么显然</p>
<script type="math/tex; mode=display">
x = \frac
{\sum_{inv = 0}^{\frac{n(n-1)}{2}} L_{inv} \cdot ans_{12}(inv)}
{n!}</script><p>但是实际上,有可能 shuffle 一次之后我们不满意,那就有可能继续 shuffle。所以我们只好列一个方程来计算 $x$。</p>
<p>我们知道,shuffle 后有一部分满意的情况(即 $ans_{12}(inv) \leq x + c$),其中每种情况的代价是 $ans_{12}(inv)$;也有一部分不满意的情况(即 $ans_{12}(inv) > x + c$),其中每种情况的代价是 $x + c$。于是我们可以把上面那个错误的式子改成这样一个正确的式子:</p>
<script type="math/tex; mode=display">
x = \frac
{\sum_{ans_{12}(inv) \leq x + c} L_{inv} \cdot ans_{12}(inv) +
\sum_{ans_{12}(inv) > x + c} L_{inv} \cdot (x + c) }
{n!}</script><p>为了方便计算这个东西,我们变换一下下标。令 $id$ 是一个排列且满足 $ans_{12}(id_i)$ 关于 $i$ 单增(用排序就可以实现),那么显然会有一个分界点 $k$ 使得</p>
<script type="math/tex; mode=display">
x = \frac
{\sum_{i = 0}^{k} L_{id_i} \cdot ans_{12}(id_i) +
\sum_{i = k + 1}^{\frac{n(n-1)}{2}} L_{id_i} \cdot (x + c) }
{n!}</script><p>把 $x$ 挪到一边</p>
<script type="math/tex; mode=display">
x = \frac
{\sum_{i = 0}^{k} L_{id_i} \cdot ans_{12}(id_i) +
\sum_{i = k + 1}^{\frac{n(n-1)}{2}} L_{id_i} \cdot c }
{n! - \sum_{i = k + 1}^{\frac{n(n-1)}{2}} L_{id_i}}</script><p>考虑到 $n! = \sum_{i=0}^{\frac{n(n-1)}{2}} L_i$,我们可以修改得好看一点</p>
<script type="math/tex; mode=display">
x + c = \frac
{\sum_{i = 0}^{k} L_{id_i} \cdot ans_{12}(id_i) + n! \cdot c}
{\sum_{i = 0}^{k} L_{id_i}}</script><p>这个方程有两个未知量 $x$ 和 $k$,但是我们不难发现它们必定满足 $ans_{12}(k) \leq x + c \leq ans_{12}(k + 1)$。然后我们预处理一下前缀和,枚举 $k$ 找合法解就可以辣!</p>
<p>$L_i$ 不会求的话,可以参考 <a href="https://www.luogu.com.cn/problem/P2513" target="_blank" rel="noopener">[HAOI2009] 逆序对数列 </a>。</p>
<h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sstream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iomanip></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> all(v) (v).begin(), (v).end()</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> unq(v) (v).erase(unique(all(v)), (v).end())</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ii int, int</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> li int, int</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ll2 ll, ll</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> vec vector</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pii pair <span class="meta-string"><int, int></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pli pair <span class="meta-string"><ll, int></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pll2 pair <span class="meta-string"><ll, ll></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> mp make_pair</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pb push_back</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> fi first</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> se second</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MULTI int T; cin >> T; while(T--)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> sqr(x) ((x) * (x))</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> test cerr << <span class="meta-string">'!'</span> << endl;</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main0</span> <span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">ifndef</span> ONLINE_JUDGE</span></span><br><span class="line"> freopen(<span class="string">"C:\\Users\\98497\\Desktop\\code\\file.in"</span>, <span class="string">"r"</span>, <span class="built_in">stdin</span>);</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"> ios::sync_with_stdio(<span class="literal">false</span>);</span><br><span class="line"> <span class="keyword">clock_t</span> start, end;</span><br><span class="line"> <span class="comment">// start = clock();</span></span><br><span class="line"> main0();</span><br><span class="line"> <span class="comment">// end = clock();</span></span><br><span class="line"> <span class="comment">// cout << (end - start) << endl;</span></span><br><span class="line"> <span class="meta">#<span class="meta-keyword">ifndef</span> ONLINE_JUDGE</span></span><br><span class="line"> fclose(<span class="built_in">stdin</span>);</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">endif</span></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><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dx[<span class="number">8</span>] = {<span class="number">0</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">-1</span>};</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dy[<span class="number">8</span>] = {<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">-1</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">-1</span>, <span class="number">1</span>};</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">20</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> M = <span class="number">200</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> INF = <span class="number">0x3f3f3f3f</span>;</span><br><span class="line"><span class="keyword">const</span> ll INFF = <span class="number">0x3f3f3f3f3f3f3f3f</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod = <span class="number">998244353</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">double</span> eps = <span class="number">1e-6</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">double</span> Pi = <span class="built_in">acos</span>(<span class="number">-1.0</span>);</span><br><span class="line"></span><br><span class="line">ll L[N][M];</span><br><span class="line">ll fac[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">init</span> <span class="params">()</span> </span>{</span><br><span class="line"> L[<span class="number">1</span>][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">2</span>;i <= <span class="number">16</span>;++i) {</span><br><span class="line"> ll pre = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>;j <= <span class="number">120</span>;++j) {</span><br><span class="line"> pre += L[i - <span class="number">1</span>][j];</span><br><span class="line"> <span class="keyword">if</span> (j - i >= <span class="number">0</span>) pre -= L[i - <span class="number">1</span>][j - i];</span><br><span class="line"> L[i][j] = pre;</span><br><span class="line"> <span class="comment">//cout << i << ' ' << j << ':' << f[i][j] << endl;</span></span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> fac[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= <span class="number">16</span>;++i) {</span><br><span class="line"> fac[i] = fac[i - <span class="number">1</span>] * i;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">ll v[N];</span><br><span class="line">ll t[M], id[M];</span><br><span class="line">ll pre1[M], pre2[M];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmp</span> <span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> y)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> t[x] < t[y];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">ll <span class="title">gcd</span> <span class="params">(ll x, ll y)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (!y) <span class="keyword">return</span> x;</span><br><span class="line"> <span class="keyword">return</span> gcd(y, x % y);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main0</span> <span class="params">()</span> </span>{</span><br><span class="line"> init();</span><br><span class="line"> MULTI {</span><br><span class="line"> ll n, a, b, c, d;</span><br><span class="line"> <span class="built_in">cin</span> >> n >> a >> b >> c >> d;</span><br><span class="line"> ll lim = n * (n - <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>;i <= lim;++i) {</span><br><span class="line"> t[i] = min(i * a, b + (lim - i) * a);</span><br><span class="line"> id[i] = i;</span><br><span class="line"> }</span><br><span class="line"> sort(id, id + lim + <span class="number">1</span>, cmp);</span><br><span class="line"> </span><br><span class="line"> pre1[<span class="number">0</span>] = L[n][<span class="number">0</span>];</span><br><span class="line"> pre2[<span class="number">0</span>] = L[n][<span class="number">0</span>] * t[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= lim;++i) {</span><br><span class="line"> pre1[i] = pre1[i - <span class="number">1</span>] + L[n][id[i]];</span><br><span class="line"> pre2[i] = pre2[i - <span class="number">1</span>] + L[n][id[i]] * t[id[i]];</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> ll k, p, q;</span><br><span class="line"> <span class="keyword">double</span> x;</span><br><span class="line"> <span class="keyword">for</span> (k = <span class="number">0</span>;k < lim;++k) {</span><br><span class="line"> p = pre2[k] + c * fac[n];</span><br><span class="line"> q = pre1[k];</span><br><span class="line"> ll gcdd = gcd(p, q);</span><br><span class="line"> p /= gcdd;</span><br><span class="line"> q /= gcdd;</span><br><span class="line"> x = <span class="number">1.0</span> * p / q;</span><br><span class="line"> <span class="comment">//cout<<k<<':'<<p<<'/'<<q<<'='<<x<<' '<<t[id[k]]<<'~'<<t[id[k+1]]<< endl;</span></span><br><span class="line"> <span class="keyword">if</span> ((t[id[k]] <= x) && (x <= t[id[k+<span class="number">1</span>]])) <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> cur = <span class="number">1</span>;cur <= d;++cur) {</span><br><span class="line"> <span class="keyword">int</span> inv = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;++i) {</span><br><span class="line"> <span class="built_in">cin</span> >> v[i];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">1</span>;j <= i - <span class="number">1</span>;++j) {</span><br><span class="line"> inv += (v[j] > v[i]);</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> (t[inv] <= x) <span class="built_in">cout</span> << t[inv] << <span class="string">'/'</span> << <span class="number">1</span> << <span class="built_in">endl</span>;</span><br><span class="line"> <span class="keyword">else</span> <span class="built_in">cout</span> << p << <span class="string">'/'</span> << q << <span class="built_in">endl</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数学</category>
<category>概率与期望</category>
</categories>
<tags>
<tag>dp</tag>
</tags>
</entry>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 G</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-G/</url>
<content><![CDATA[<h1 id="Problem-G-Invited-Speakers"><a href="#Problem-G-Invited-Speakers" class="headerlink" title="Problem G. Invited Speakers"></a>Problem G. Invited Speakers</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给定 $2n$ 个不同的点 $(x_i,y_i)$,$A$ 类型和 $B$ 类型各 $n$ 个,保证不存在三点共线。希望你能给出一种方案把它们配对成 $n$ 对 $AB$,并且每对 $AB$ 之间用折线($[1, 100]$ 条首尾相连的线段)相连,折线之间两两不交。有 $z$ 组测试数据。</p>
<p>$1 \leq z \leq 200$</p>
<p>$1 \leq n \leq 6$</p>
<p>$0 \leq |x_i|,|y_i| \leq 100$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>我读的题,第一反应是:就这?</p>
<p>还害我确认了好几遍题意和数据范围。</p>
<p><del>精通脚撕 FFT 的各种姿势的</del>队友 Luowaterbi 曾经告诉我,没有三点共线的时候,两种一样多的点必然存在一种配对方案使得每对之间只用一条线段相连并且所有线段都不交。既然这题数据范围这么小,直接大力枚举配对方案,再大力枚举判断是否存在两线段交就行了。时间复杂度 $O(n!n^2)$。</p>
<p>由于我计算几何过于垃圾不想写,我就交给 triple_a 写了。triple_a 写得也很有意思,没用到计算几何的线段交判定,直接 $O(n!n)$ 取所有线段长度之和最小的方案,而这其实就是所有线段都不交的那个方案。</p>
<p>官方题解是个构造,懒得看具体折线怎么画了,反正意义不大,出题人可能是没想到有结论。</p>
<h2 id="Code-By-triple-a"><a href="#Code-By-triple-a" class="headerlink" title="Code (By triple_a)"></a>Code (By triple_a)</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><bits/stdc++.h></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> t,n;</span><br><span class="line"><span class="keyword">int</span> p[<span class="number">7</span>],res[<span class="number">7</span>];</span><br><span class="line">pair<<span class="keyword">int</span>,<span class="keyword">int</span>> a[<span class="number">7</span>],b[<span class="number">7</span>];</span><br><span class="line"><span class="keyword">double</span> dist;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span>{</span><br><span class="line"> <span class="built_in">cin</span>>>t;</span><br><span class="line"> <span class="keyword">while</span> (t--){</span><br><span class="line"> <span class="built_in">cin</span>>>n;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<n;++i){</span><br><span class="line"> <span class="built_in">cin</span>>>a[i].first>>a[i].second;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<n;++i){</span><br><span class="line"> <span class="built_in">cin</span>>>b[i].first>>b[i].second;</span><br><span class="line"> }</span><br><span class="line"> dist=<span class="number">1e9</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<n;++i){</span><br><span class="line"> p[i]=i;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">auto</span> f=[&](pair<<span class="keyword">int</span>,<span class="keyword">int</span>>u, pair<<span class="keyword">int</span>,<span class="keyword">int</span>> v){</span><br><span class="line"> <span class="keyword">return</span> (u.first-v.first)*(u.first-v.first)+(u.second-v.second)*(u.second-v.second);</span><br><span class="line"> };</span><br><span class="line"> <span class="keyword">do</span>{</span><br><span class="line"> <span class="keyword">double</span> sum=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<n;++i){</span><br><span class="line"> sum+=<span class="built_in">sqrt</span>(f(a[i],b[p[i]]));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (sum<dist){</span><br><span class="line"> dist=sum;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<n;++i){</span><br><span class="line"> res[i]=p[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }<span class="keyword">while</span>(next_permutation(p,p+n));</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i<n;++i){</span><br><span class="line"> <span class="built_in">cout</span><<<span class="number">2</span><<<span class="string">" "</span><<a[i].first<<<span class="string">" "</span><<a[i].second<<<span class="string">" "</span><<b[res[i]].first<<<span class="string">" "</span><<b[res[i]].second<<<span class="built_in">endl</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>计算几何</category>
</categories>
<tags>
<tag>计算几何</tag>
</tags>
</entry>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 H</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-H/</url>
<content><![CDATA[<h1 id="Problem-H-Lighthouses"><a href="#Problem-H-Lighthouses" class="headerlink" title="Problem H. Lighthouses"></a>Problem H. Lighthouses</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给一个有 $n$ 个顶点的凸多边形,其顶点用 $(x_i,y_i)$ 表示。以 $n$ 个顶点为结点,给定 $m$ 条边 $(u_i,v_i)$。希望求出图上最长的(指欧几里得距离)且不和自己相交的(几何意义上)路的长度。有 $z$ 组测试数据。</p>
<p>$3 \leq n \leq 300$, $0 \leq m \leq \frac{n(n-1)}{2}$, $1 \leq u_i \neq v_i \leq n$</p>
<p>$-10^9 \leq x_i, y_i \leq 10^9$</p>
<p>$\sum n \leq 3000$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>这题赛中我读都没读就被 clp012345 切了,赛后才看。</p>
<p>经过观察我们发现其实合法的路只能是在环上往一个方向转,那么我们上一个区间 DP 就可以了。开三个维度,分别表示起点、终点、顺/逆时针,状态转移 $O(n)$ 枚举。时间复杂度 $O(n^3)$。</p>
<p>区间 DP 要上环的话,通常做法就是开两倍数组复制一遍吧,参考石子合并。</p>
<h2 id="Code-By-clp012345"><a href="#Code-By-clp012345" class="headerlink" title="Code (By clp012345)"></a>Code (By clp012345)</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><bits/stdc++.h></span></span></span><br><span class="line"> </span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FOE(i, s, t) for (int i = s; i <= t; i++)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FOR(i, s, t) for (int i = s; i < t; i++)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> K 601</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> M 1000000007</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> LL long long</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> n;</span><br><span class="line"><span class="keyword">int</span> x[K], y[K];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">double</span> <span class="title">dist</span><span class="params">(<span class="keyword">int</span> id1, <span class="keyword">int</span> id2)</span> </span>{</span><br><span class="line"> <span class="keyword">double</span> dx = <span class="built_in">abs</span>(x[id1] - x[id2]);</span><br><span class="line"> <span class="keyword">double</span> dy = <span class="built_in">abs</span>(y[id1] - y[id2]);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> <span class="built_in">sqrt</span>(dx * dx + dy * dy); </span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> ok[K][K][<span class="number">2</span>];</span><br><span class="line"><span class="keyword">double</span> dp[K][K][<span class="number">2</span>];</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> has[K][K];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">prev</span><span class="params">(<span class="keyword">int</span> u)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> (u == <span class="number">1</span> ? n : u - <span class="number">1</span>); </span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">nxt</span><span class="params">(<span class="keyword">int</span> u)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> (u == n ? <span class="number">1</span> : u + <span class="number">1</span>); </span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">double</span> <span class="title">solve2</span><span class="params">(<span class="keyword">int</span> sta, <span class="keyword">int</span> fin, <span class="keyword">int</span> dir)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (sta == fin) <span class="keyword">return</span> <span class="number">0.00</span>;</span><br><span class="line"> <span class="keyword">if</span> (ok[sta][fin][dir] == <span class="number">0</span>) {</span><br><span class="line"> dp[sta][fin][dir] = <span class="number">0.00</span>;</span><br><span class="line"> ok[sta][fin][dir] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (dir == <span class="number">1</span>) {</span><br><span class="line"> <span class="comment">// clockwise</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = nxt(sta); i != fin; i = nxt(i)) {</span><br><span class="line"> <span class="comment">// printf("sta %d fin %d i %d %d\n", sta, fin, i, has[sta][i]);</span></span><br><span class="line"> <span class="keyword">if</span> (has[sta][i]) {</span><br><span class="line"> dp[sta][fin][dir] = max(dp[sta][fin][dir], max(solve2(i, fin, <span class="number">1</span>), solve2(i, sta, <span class="number">0</span>)) + dist(sta, i));</span><br><span class="line"> }</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="comment">// anti clockwise</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = prev(sta); i != fin; i = prev(i)) {</span><br><span class="line"> <span class="keyword">if</span> (has[sta][i]) {</span><br><span class="line"> dp[sta][fin][dir] = max(dp[sta][fin][dir], max(solve2(i, fin, <span class="number">0</span>), solve2(i, sta, <span class="number">1</span>)) + dist(sta, i));</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">return</span> dp[sta][fin][dir];</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">solve</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n) <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &x[i], &y[i]);</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n) FOE(j, <span class="number">1</span>, n) ok[i][j][<span class="number">0</span>] = ok[i][j][<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">double</span> ret = <span class="number">0.00</span>;</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n) FOE(j, <span class="number">1</span>, n) has[i][j] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">int</span> m; <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &m);</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, m) {</span><br><span class="line"> <span class="keyword">int</span> u, v; <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &u, &v);</span><br><span class="line"> has[u][v] = has[v][u] = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n) FOE(j, <span class="number">1</span>, n) <span class="keyword">if</span> (has[i][j]) {</span><br><span class="line"> <span class="keyword">double</span> temp = max(solve2(j, i, <span class="number">1</span>), solve2(j, i, <span class="number">0</span>)) + dist(i, j);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (temp > ret) ret = temp; </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%.9f\n"</span>, ret);</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> t; <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &t);</span><br><span class="line"> <span class="keyword">while</span> (t--) solve();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>动态规划</category>
<category>区间DP</category>
</categories>
<tags>
<tag>区间dp</tag>
</tags>
</entry>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 I</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-I/</url>
<content><![CDATA[<h1 id="Problem-I-Sum-of-Palindromes"><a href="#Problem-I-Sum-of-Palindromes" class="headerlink" title="Problem I. Sum of Palindromes"></a>Problem I. Sum of Palindromes</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>把给定的 $n$ 位数分解成不超过 $25$ 个回文数(不允许前导零)。有 $z$ 组测试数据。</p>
<p>$1 \leq z \leq 20000$</p>
<p>$1 \leq n \leq 10^5$</p>
<p>$\sum n \leq 3 \times 10^6$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>跟国内比赛撞车了(2016 CCPC Changchun J),可能这些毛子出题人没怎么看国内比赛的题。</p>
<p>做法很简单,就是每次减掉小于当前数的最大的回文数。很显然每次可以减掉一半的长度,所以大概只需要 $\log n$ 次就够了。唯一的难点在于实现有点恶心,需要上高精度,不过我直接复制以前打 16 长春时候的代码了。(那个时候写得很丑不要骂我呜呜呜)</p>
<h2 id="Code-By-Nanako"><a href="#Code-By-Nanako" class="headerlink" title="Code (By Nanako)"></a>Code (By Nanako)</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">2e5</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">char</span> s[N];</span><br><span class="line"><span class="keyword">int</span> a[N], b[N], c[N];</span><br><span class="line"><span class="keyword">int</span> ans[<span class="number">55</span>][N];</span><br><span class="line"><span class="keyword">int</span> cnt = <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> T;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &T);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> it = <span class="number">1</span>;it <= T;it++) {</span><br><span class="line"> cnt = <span class="number">0</span>;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>, &s);</span><br><span class="line"> a[<span class="number">0</span>] = <span class="built_in">strlen</span>(s);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>;i < a[<span class="number">0</span>];i++) {</span><br><span class="line"> a[a[<span class="number">0</span>] - i] = s[i] - <span class="number">48</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (a[a[<span class="number">0</span>]] == <span class="number">0</span>) a[<span class="number">0</span>]--;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span> (a[<span class="number">0</span>] > <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">if</span> ((a[<span class="number">0</span>] == <span class="number">2</span>) && (a[<span class="number">2</span>] == <span class="number">1</span>) && (a[<span class="number">1</span>] == <span class="number">0</span>)) <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= a[<span class="number">0</span>];i++) b[i] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = a[<span class="number">0</span>];i >= (a[<span class="number">0</span>] + <span class="number">1</span>) / <span class="number">2</span>;i--) {</span><br><span class="line"> b[i] = a[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> p = (a[<span class="number">0</span>] & <span class="number">1</span>) ? (a[<span class="number">0</span>] + <span class="number">1</span>) / <span class="number">2</span> : a[<span class="number">0</span>] / <span class="number">2</span> + <span class="number">1</span>;</span><br><span class="line"> b[p]--;</span><br><span class="line"> <span class="keyword">while</span> (b[p] < <span class="number">0</span>) {</span><br><span class="line"> b[p] += <span class="number">10</span>;</span><br><span class="line"> b[++p]--;</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//for (int i = a[0];i >= 1;i--) cout << b[i];cout << " b" << endl;</span></span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= a[<span class="number">0</span>];i++) c[i] = <span class="number">0</span>;</span><br><span class="line"> c[<span class="number">0</span>] = a[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = a[<span class="number">0</span>];i >= (a[<span class="number">0</span>] + <span class="number">1</span>) / <span class="number">2</span>;i--) {</span><br><span class="line"> c[i] = b[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= (a[<span class="number">0</span>] + <span class="number">1</span>) / <span class="number">2</span>;i++) {</span><br><span class="line"> c[i] = b[a[<span class="number">0</span>] - i + <span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (b[a[<span class="number">0</span>]] == <span class="number">0</span>) c[<span class="number">1</span>] = <span class="number">9</span>;</span><br><span class="line"> <span class="keyword">while</span> (c[c[<span class="number">0</span>]] == <span class="number">0</span>) c[<span class="number">0</span>]--;</span><br><span class="line"> <span class="comment">//for (int i = a[0];i >= 1;i--) cout << c[i];cout << " c" << endl;</span></span><br><span class="line"> </span><br><span class="line"> ans[++cnt][<span class="number">0</span>] = c[<span class="number">0</span>];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= c[<span class="number">0</span>];i++) {</span><br><span class="line"> ans[cnt][i] = c[i];</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= a[<span class="number">0</span>];i++) {</span><br><span class="line"> a[i] -= c[i];</span><br><span class="line"> <span class="keyword">if</span> (a[i] < <span class="number">0</span>) {</span><br><span class="line"> a[i + <span class="number">1</span>]--;</span><br><span class="line"> a[i] += <span class="number">10</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span> (a[a[<span class="number">0</span>]] == <span class="number">0</span>) a[<span class="number">0</span>]--;</span><br><span class="line"> <span class="comment">//for (int i = a[0];i >= 1;i--) cout << a[i];cout << a[0] << " a" << endl;</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (a[<span class="number">0</span>] == <span class="number">1</span>) {</span><br><span class="line"> ans[++cnt][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> ans[cnt][<span class="number">1</span>] = a[<span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (a[<span class="number">0</span>] == <span class="number">2</span>) {</span><br><span class="line"> ans[++cnt][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> ans[cnt][<span class="number">1</span>] = <span class="number">9</span>;</span><br><span class="line"> ans[++cnt][<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> ans[cnt][<span class="number">1</span>] = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,cnt);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= cnt;i++) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = ans[i][<span class="number">0</span>];j >= <span class="number">1</span>;j--) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d"</span>, ans[i][j]);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"\n"</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>高精度</category>
</categories>
<tags>
<tag>高精度</tag>
</tags>
</entry>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 J</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-J/</url>
<content><![CDATA[<h1 id="Problem-J-Space-Gophers"><a href="#Problem-J-Space-Gophers" class="headerlink" title="Problem J. Space Gophers"></a>Problem J. Space Gophers</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>有一个由边长为 $1$ 的小正方体组成的边长为 $10^6$ 的实心正方体。在其中挖 $n$ 条隧道,每条隧道用 $(-,y_i,z_i)$ 或 $(x_i,-,z_i)$ 或 $(x_i,y_i,-)$ 表示。挖隧道的含义是,指定其中两个维度的坐标,沿平行于另一个维度轴线的方向把 $10^6$ 个方块拿走。挖完 $n$ 条隧道之后,$q$ 次询问两个点 $(s_x,s_y,s_z)$ 和 $(t_x,t_y,t_z)$ 是否可以通过若干条隧道连通。保证 $s$ 和 $t$ 处于隧道中。有 $z$ 组测试数据。</p>
<p>$1 \leq z \leq 6$</p>
<p>$1 \leq n \leq 3 \times 10^5$, $1 \leq x_i,y_i,z_i \leq 10^6$</p>
<p>$1 \leq q \leq 5 \times 10^5$, $1 \leq s_x,s_y,s_z,t_x,t_y,t_z \leq 10^6$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>clp 单切之前大致跟我讲了一下做法。实际上两条隧道连通 iff 某一个维度坐标相等或相差 1,于是我们要做的事情就是把所有这样的隧道对找出来,在并查集上 merge 起来。</p>
<p>这个东西说起来简单,实现起来就比较呕吐……具体还是看代码吧……<del>似乎是这篇文章里最长的代码</del></p>
<h2 id="Code-By-clp012345"><a href="#Code-By-clp012345" class="headerlink" title="Code (By clp012345)"></a>Code (By clp012345)</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><bits/stdc++.h></span></span></span><br><span class="line"> </span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FOE(i, s, t) for (int i = s; i <= t; i++)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FOR(i, s, t) for (int i = s; i < t; i++)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> K 5000001</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> D 1000000</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> mp make_pair</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pb push_back</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> LL long long</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> nxt[K], sz[K];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">par</span><span class="params">(<span class="keyword">int</span> u)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> (nxt[u] == u ? u : nxt[u] = par(nxt[u])); </span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">merge</span><span class="params">(<span class="keyword">int</span> u, <span class="keyword">int</span> v)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> s1 = par(u);</span><br><span class="line"> <span class="keyword">int</span> s2 = par(v);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (s1 == s2) <span class="keyword">return</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (sz[s1] > sz[s2]) swap(s1, s2);</span><br><span class="line"> </span><br><span class="line"> nxt[s1] = s2;</span><br><span class="line"> sz[s2] += sz[s1];</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> n;</span><br><span class="line"> </span><br><span class="line"><span class="built_in">vector</span><<span class="keyword">int</span>> x[D + <span class="number">100</span>], y[D + <span class="number">100</span>], z[D + <span class="number">100</span>];</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> goodX[D], goodY[D], goodZ[D];</span><br><span class="line"> </span><br><span class="line"><span class="built_in">map</span><pair<pair<<span class="keyword">int</span>, <span class="keyword">int</span>>, <span class="keyword">int</span>>, <span class="keyword">int</span> > M;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> px[D], py[D], pz[D];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">seek</span><span class="params">(<span class="keyword">int</span> x, <span class="keyword">int</span> y, <span class="keyword">int</span> z)</span> </span>{</span><br><span class="line"><span class="comment">// printf("seek %d %d %d ? %d %d %d \n", x, y, z, M[mp(mp(x, y), -1)], M[mp(mp(x, -1), z)], M[mp(mp(-1, y), z)]);</span></span><br><span class="line"> <span class="keyword">int</span> a1 = M[mp(mp(x, y), <span class="number">-1</span>)];</span><br><span class="line"> <span class="keyword">if</span> (a1) <span class="keyword">return</span> a1;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> a2 = M[mp(mp(x, <span class="number">-1</span>), z)];</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (a2) <span class="keyword">return</span> a2;</span><br><span class="line"> <span class="keyword">return</span> M[mp(mp(<span class="number">-1</span>, y), z)];</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> q;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">solve</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> </span><br><span class="line"> M.clear(); </span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, D) {</span><br><span class="line"> x[i].clear(); y[i].clear(); z[i].clear(); </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>, &px[i], &py[i], &pz[i]);</span><br><span class="line"> </span><br><span class="line"> M[mp(mp(px[i], py[i]), pz[i])] = i;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (px[i] != <span class="number">-1</span>) {</span><br><span class="line"> x[px[i]].pb(i);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (py[i] != <span class="number">-1</span>) {</span><br><span class="line"> y[py[i]].pb(i); </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (pz[i] != <span class="number">-1</span>) {</span><br><span class="line"> z[pz[i]].pb(i); </span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n + <span class="number">3</span> * D) {</span><br><span class="line"> nxt[i] = i;</span><br><span class="line"> sz[i] = <span class="number">1</span>; </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n) {</span><br><span class="line"> <span class="keyword">if</span> (pz[i] == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> dx = <span class="number">0</span>; dx <= <span class="number">1</span>; dx++) <span class="keyword">for</span> (<span class="keyword">int</span> dy = <span class="number">0</span>; dy <= <span class="number">1</span>; dy++) <span class="keyword">if</span> (<span class="built_in">abs</span>(dx) + <span class="built_in">abs</span>(dy) == <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">int</span> id2 = M[mp(mp(px[i] + dx, py[i] + dy), <span class="number">-1</span>)];</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (id2) merge(id2, i);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (py[i] == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> dx = <span class="number">0</span>; dx <= <span class="number">1</span>; dx++) <span class="keyword">for</span> (<span class="keyword">int</span> dz = <span class="number">0</span>; dz <= <span class="number">1</span>; dz++) <span class="keyword">if</span> (<span class="built_in">abs</span>(dx) + <span class="built_in">abs</span>(dz) == <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">int</span> id2 = M[mp(mp(px[i] + dx, <span class="number">-1</span>), pz[i] + dz)];</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (id2) merge(id2, i);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (px[i] == <span class="number">-1</span>) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> dy = <span class="number">0</span>; dy <= <span class="number">1</span>; dy++) <span class="keyword">for</span> (<span class="keyword">int</span> dz = <span class="number">0</span>; dz <= <span class="number">1</span>; dz++) <span class="keyword">if</span> (<span class="built_in">abs</span>(dy) + <span class="built_in">abs</span>(dz) == <span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">int</span> id2 = M[mp(mp(<span class="number">-1</span>, py[i] + dy), pz[i] + dz)];</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (id2) merge(id2, i);</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"> FOE(i, <span class="number">1</span>, D) {</span><br><span class="line"> <span class="keyword">int</span> g1 = <span class="number">0</span>, g2 = <span class="number">0</span>;</span><br><span class="line"> FOR(j, <span class="number">0</span>, x[i].size()) {</span><br><span class="line"> <span class="keyword">int</span> id = x[i][j];</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (py[id] == <span class="number">-1</span>) g1 = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (pz[id] == <span class="number">-1</span>) g2 = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> goodX[i] = g1 * <span class="number">2</span> + g2;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOR(i, <span class="number">1</span>, D) {</span><br><span class="line"> <span class="keyword">if</span> ((goodX[i] | goodX[i + <span class="number">1</span>]) == <span class="number">3</span>) {</span><br><span class="line"> FOR(j, <span class="number">0</span>, x[i].size()) merge(i + n, x[i][j]);</span><br><span class="line"> FOR(j, <span class="number">0</span>, x[i + <span class="number">1</span>].size()) merge(i + n, x[i + <span class="number">1</span>][j]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, D) {</span><br><span class="line"> <span class="keyword">int</span> g1 = <span class="number">0</span>, g2 = <span class="number">0</span>;</span><br><span class="line"> FOR(j, <span class="number">0</span>, y[i].size()) {</span><br><span class="line"> <span class="keyword">int</span> id = y[i][j];</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (px[id] == <span class="number">-1</span>) g1 = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (pz[id] == <span class="number">-1</span>) g2 = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> goodY[i] = g1 * <span class="number">2</span> + g2;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOR(i, <span class="number">1</span>, D) {</span><br><span class="line"> <span class="keyword">if</span> ((goodY[i] | goodY[i + <span class="number">1</span>]) == <span class="number">3</span>) {</span><br><span class="line"> FOR(j, <span class="number">0</span>, y[i].size()) merge(i + D + n, y[i][j]);</span><br><span class="line"> FOR(j, <span class="number">0</span>, y[i + <span class="number">1</span>].size()) merge(i + D + n, y[i + <span class="number">1</span>][j]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, D) {</span><br><span class="line"> <span class="keyword">int</span> g1 = <span class="number">0</span>, g2 = <span class="number">0</span>;</span><br><span class="line"> FOR(j, <span class="number">0</span>, z[i].size()) {</span><br><span class="line"> <span class="keyword">int</span> id = z[i][j];</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (px[id] == <span class="number">-1</span>) g1 = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (py[id] == <span class="number">-1</span>) g2 = <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> goodZ[i] = g1 * <span class="number">2</span> + g2;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOR(i, <span class="number">1</span>, D) {</span><br><span class="line"> <span class="keyword">if</span> ((goodZ[i] | goodZ[i + <span class="number">1</span>]) == <span class="number">3</span>) {</span><br><span class="line"> FOR(j, <span class="number">0</span>, z[i].size()) merge(i + <span class="number">2</span> * D + n, z[i][j]);</span><br><span class="line"> FOR(j, <span class="number">0</span>, z[i + <span class="number">1</span>].size()) merge(i + <span class="number">2</span> * D + n, z[i + <span class="number">1</span>][j]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &q);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span> (q--) {</span><br><span class="line"> <span class="keyword">int</span> a1, a2, a3, a4, a5, a6;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d%d%d%d"</span>, &a1, &a2, &a3, &a4, &a5, &a6);</span><br><span class="line"> <span class="keyword">int</span> id1 = seek(a1, a2, a3);</span><br><span class="line"> <span class="keyword">int</span> id2 = seek(a4, a5, a6);</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// printf("conv %d %d\n", id1, id2);</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (par(id1) == par(id2)) {</span><br><span class="line"> <span class="built_in">puts</span>(<span class="string">"YES"</span>); </span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">puts</span>(<span class="string">"NO"</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 class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> t; <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &t);</span><br><span class="line"> <span class="keyword">while</span> (t--) solve();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数据结构</category>
<category>并查集</category>
</categories>
<tags>
<tag>并查集</tag>
</tags>
</entry>
<entry>
<title>2020 Petrozavodsk Winter Camp Day 5 L</title>
<url>/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-L/</url>
<content><![CDATA[<h1 id="Problem-L-Wizards-Unite"><a href="#Problem-L-Wizards-Unite" class="headerlink" title="Problem L. Wizards Unite"></a>Problem L. Wizards Unite</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给 $1$ 把金钥匙(可多次使用的钥匙),$k$ 把银钥匙(只能用一次)。给 $n$ 个箱子,每个箱子有一个打开所需时间 $t_i$(跟钥匙类型无关)。一把钥匙同时只能开一个箱子,问打开所有箱子所需的最小总时间。有 $z$ 组测试数据。</p>
<p>$0 \leq k < n \leq 10^5$</p>
<p>$0 \leq t_i \leq 10^9$</p>
<p>$\sum n \leq 10^6$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>本场最简单的题。</p>
<p>不失一般性,我们认为所有箱子按 $t_i$ 排升序。显然方案只能是 $k$ 把银钥匙都用来开一个箱子,金钥匙开其他所有箱子,而答案就是以下两者中的较大值:用银钥匙的箱子中耗时最长的一个的耗时;金钥匙开其他所有箱子的耗时之和。</p>
<p>注意到答案无论如何也不可能小于 $t_n$,也就是说用银钥匙开 $t_n$ 箱子一定不会浪费时间。那么为了令金钥匙耗时之和尽可能小,实际上 $k$ 把银钥匙开的就是最右边的 $k$ 个箱子,于是答案就很显然了。时间复杂度 $O(n \log n)$。</p>
<p>我读的,读完第一反应居然是二分答案找一个分界点使得银钥匙开的是这个分界点左边的 $k$ 个……要说的话虽然更慢<del>(我写的是 $O(n \log^2 n)$……)</del>但是结果也是对的,但我一个大于写成了大于等于交了一发 WA……签到题都 WA,很惭愧……</p>
<p>下面的代码还是赛中交的二分答案版本,反正正解上面说的很清楚了,也很简单,懒得再写了。</p>
<h2 id="Code-By-Nanako"><a href="#Code-By-Nanako" class="headerlink" title="Code (By Nanako)"></a>Code (By Nanako)</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sstream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iomanip></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><string></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> all(v) (v).begin(), (v).end()</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> unq(v) (v).erase(unique(all(v)), (v).end())</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ii int, int</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> li int, int</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ll2 ll, ll</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> vec vector</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pii pair <span class="meta-string"><int, int></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pli pair <span class="meta-string"><ll, int></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pll2 pair <span class="meta-string"><ll, ll></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> mp make_pair</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> pb push_back</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> fi first</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> se second</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MULTI int T; cin >> T; while(T--)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> sqr(x) ((x) * (x))</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> test cerr << <span class="meta-string">'!'</span> << endl;</span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main0</span> <span class="params">()</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">ifndef</span> ONLINE_JUDGE</span></span><br><span class="line"> freopen(<span class="string">"C:\\Users\\98497\\Desktop\\code\\file.in"</span>, <span class="string">"r"</span>, <span class="built_in">stdin</span>);</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line"> ios::sync_with_stdio(<span class="literal">false</span>);</span><br><span class="line"> <span class="keyword">clock_t</span> start, end;</span><br><span class="line"> <span class="comment">// start = clock();</span></span><br><span class="line"> main0();</span><br><span class="line"> <span class="comment">// end = clock();</span></span><br><span class="line"> <span class="comment">// cout << (end - start) << endl;</span></span><br><span class="line"> <span class="meta">#<span class="meta-keyword">ifndef</span> ONLINE_JUDGE</span></span><br><span class="line"> fclose(<span class="built_in">stdin</span>);</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">endif</span></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><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dx[<span class="number">8</span>] = {<span class="number">0</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">0</span>, <span class="number">1</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">-1</span>};</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dy[<span class="number">8</span>] = {<span class="number">1</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">-1</span>, <span class="number">1</span>, <span class="number">-1</span>, <span class="number">-1</span>, <span class="number">1</span>};</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">2e5</span> + <span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> M = <span class="number">1e5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> INF = <span class="number">0x3f3f3f3f</span>;</span><br><span class="line"><span class="keyword">const</span> ll INFF = <span class="number">0x3f3f3f3f3f3f3f3f</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod = <span class="number">998244353</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">double</span> eps = <span class="number">1e-6</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">double</span> Pi = <span class="built_in">acos</span>(<span class="number">-1.0</span>);</span><br><span class="line"> </span><br><span class="line">ll a[N];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main0</span> <span class="params">()</span> </span>{</span><br><span class="line"> MULTI {</span><br><span class="line"> <span class="keyword">int</span> n, k;</span><br><span class="line"> <span class="built_in">cin</span> >> n >> k;</span><br><span class="line"> ll sum = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;++i) {</span><br><span class="line"> <span class="built_in">cin</span> >> a[i];</span><br><span class="line"> sum += a[i];</span><br><span class="line"> }</span><br><span class="line"> sort(a + <span class="number">1</span>, a + n + <span class="number">1</span>);</span><br><span class="line"> </span><br><span class="line"> ll l = <span class="number">0</span>, r = sum;</span><br><span class="line"> <span class="keyword">while</span> (l <= r) {</span><br><span class="line"> ll mid = (l + r + <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">int</span> pos = upper_bound(a + <span class="number">1</span>, a + n + <span class="number">1</span>, mid) - a; pos--;</span><br><span class="line"> ll silver = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = max(<span class="number">1</span>, pos - k + <span class="number">1</span>);i <= pos;++i) silver += a[i];</span><br><span class="line"> <span class="comment">//cout << l << ' ' << r << ' ' << mid << ':' << pos << ' ' << silver << endl;</span></span><br><span class="line"> <span class="keyword">if</span> (sum - silver > mid) l = mid + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> r = mid - <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">cout</span> << l << <span class="built_in">endl</span>;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>结论/规律</category>
</categories>
<tags>
<tag>结论/规律</tag>
</tags>
</entry>
<entry>
<title>[20200426] 2020 Petrozavodsk Winter Camp Day 5</title>
<url>/2020/06/02/20200426-2020-Petrozavodsk-Winter-Camp-Day-5/</url>
<content><![CDATA[<h1 id="Review"><a href="#Review" class="headerlink" title="Review"></a>Review</h1><p><a href="https://codeforces.com/profile/triple__a" target="_blank" rel="noopener">triple_a</a> 问我和 <a href="https://codeforces.com/profile/nezzar" target="_blank" rel="noopener">clp012345</a> 要不要来玩,于是我就打了<del>,前 World Finalist 带飞谁不爱呢</del>。</p>
<p>因为纯属娱乐所以可能并不是全力打,不过也并没有做到同一时刻只有一个人写……总之就是图一乐吧。</p>
<p>刚开场的时候因为是娱乐所以他们两个也就随便开题不跟榜了,我们各自读了一下几道题。clp012345 开始猛凹 C 凹了接近两个小时<del>,结果是 C 最后也没过</del>。我看到有人过 L 就大力 WA 了一发,发现把大于写成大于等于,<strong>43min2A</strong>。B 题 triple_a 说只会 TLE 的枚举子集,于是 clp012345 说 Sum over Submask DP 能做,<strong>51min1A</strong>。triple_a 又读了 I 题,说做法显然但是难写,我一看题居然是原题(2016 CCPC Changchun J),可能毛子出题人没看过国内这场,于是直接复制粘贴交了,<strong>71min1A</strong>。G 我之前就说是大力枚举,但我不会计算几何,让 triple_a 写了,<strong>105min2A</strong>。我们交流了一下 F 的题意,然后 triple_a 觉得他大概会写,然后他说反正是随便打打所以他有事要出门了(草)。我大力猜了一下 A 题有个结论,但是需要筛 $10^{11}$ 以内的质数个数,时间复杂度没法接受,clp012345 告诉我有一种叫作 <a href="https://tanakarino.cn/2020/04/27/Meissel-Lehmer算法/">Meissel-Lehmer</a> 的神棍算法可以 $O(n^\frac 23)$ 求这个东西……找了个板子复制粘贴(?),然后我搞错边界,又贡献一发罚时,<strong>156min2A</strong>。期间 clp012345 单切了 H(我题都没读……),<strong>167min2A</strong>。<del>接下来我假装看 C 和 E,其实已经没思路了完全躺了。</del>但他们两个还是很猛,clp012345 单切了 J,<strong>230min4A</strong>。triple_a 回来把 F 写了,<strong>257min2A</strong>。我跟 clp012345 说 E 题的圆其实就是竖线,他说用离散化线段树维护一下就行,<strong>293min4A</strong>。</p>
<p>前 World Finalist 带飞果然牛逼,9 个题<del>,力压 dmy</del>,我全程躺着被带飞。</p>
<h1 id="Solution(待完善)"><a href="#Solution(待完善)" class="headerlink" title="Solution(待完善)"></a>Solution(待完善)</h1><h2 id="Problem-A-Bags-of-Candies"><a href="#Problem-A-Bags-of-Candies" class="headerlink" title="Problem A. Bags of Candies"></a>Problem A. Bags of Candies</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-A/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-A/</a></p>
<h2 id="Problem-B-Binomial"><a href="#Problem-B-Binomial" class="headerlink" title="Problem B. Binomial"></a>Problem B. Binomial</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-B/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-B/</a></p>
<h2 id="Problem-C-Bookface"><a href="#Problem-C-Bookface" class="headerlink" title="Problem C. Bookface"></a>Problem C. Bookface</h2><p>大致题意:数轴上有 $n$ 个点 $a_1,a_2,\dots,a_n$,每次你可以花费 $1$ 代价使某个点向某个方向移动 $1$(但所有点必须时刻在正半轴上)。现在,希望你求出最小总代价,使得任意两点间的距离都大于等于 $d$。有 $z$ 组测试数据。</p>
<p>$1 \leq z \leq 10^5$</p>
<p>$1 \leq n \leq 2 \times 10^5$, $1 \leq d \leq 10^6$, $0 \leq a_i \leq 3 \times 10^{11}$</p>
<p>$\sum n \leq 10^6$</p>
<h3 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h3><p>World Finalist 凹了两个小时都没出的题,鸽。</p>
<h2 id="Problem-D-Clique"><a href="#Problem-D-Clique" class="headerlink" title="Problem D. Clique"></a>Problem D. Clique</h2><p>没读,全场最不可做的题。</p>
<h2 id="Problem-E-Contamination"><a href="#Problem-E-Contamination" class="headerlink" title="Problem E. Contamination"></a>Problem E. Contamination</h2><p>triple_a 给我说的大致题意:平面上,给定 $n$ 个圆 $(c_x, c_y, r)$ 以及 $q$ 个询问 $(p_x,p_y,q_x,q_y,y_{min},y_{max})$,问能不能从 $(p_x,p_y) $ 走到 $(q_x,q_y)$,并满足路线不能碰到圆且任意时刻都有 $y \in [y_{min},y_{max}]$。</p>
<p>$1 \leq n, q \leq 10^6$</p>
<p>$-10^9 \leq c_x, c_y \leq 10^9$, $1 \leq r \leq 10^9$</p>
<p>$-10^9 \leq p_x,p_y,q_x,q_y,y_{min},y_{max} \leq 10^9$, $y_{min} \leq p_y, q_y \leq y_{max}$</p>
<p>一直到最后一个小时,我都是按这个题意理解的。我提出,如果圆两两不交,那么圆其实等价于其平行于 $y$ 轴的直径;但圆如果相交,就没有任何办法可做。最后一个小时 clp012345 来看 E,他自己读了一遍题,然后告诉我,题目里面说了圆是不交的……</p>
<h3 id="Solution-1"><a href="#Solution-1" class="headerlink" title="Solution"></a>Solution</h3><p>但我没想到怎么维护这个东西,clp012345 说就是一棵离散化线段树。有空的时候再具体问他。</p>
<h3 id="Code-By-clp012345"><a href="#Code-By-clp012345" class="headerlink" title="Code (By clp012345)"></a>Code (By clp012345)</h3><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><bits/stdc++.h></span></span></span><br><span class="line"> </span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FOE(i, s, t) for (int i = s; i <= t; i++)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FOR(i, s, t) for (int i = s; i < t; i++)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> K 2300001</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> M 1000000007</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> NINF -2002100100</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> LL long long</span></span><br><span class="line"> </span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> n, q;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">P</span> {</span></span><br><span class="line"> <span class="keyword">int</span> x, y, r; </span><br><span class="line">};</span><br><span class="line"> </span><br><span class="line">P p[K];</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> cx[<span class="number">2</span> * K];</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Q</span> {</span></span><br><span class="line"> <span class="keyword">int</span> sx, ymin, ymax, ex, id; </span><br><span class="line">};</span><br><span class="line"> </span><br><span class="line">Q qu[K];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmpY</span><span class="params">(P A, P B)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> A.y < B.y; </span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmpQY</span><span class="params">(Q A, Q B)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> A.ymin < B.ymin; </span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> l[<span class="number">4</span> * K], r[<span class="number">4</span> * K];</span><br><span class="line">LL a[<span class="number">4</span> * K];</span><br><span class="line"><span class="keyword">int</span> h;</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> sol[K];</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">build</span><span class="params">(<span class="keyword">int</span> u, <span class="keyword">int</span> lb, <span class="keyword">int</span> rb)</span> </span>{</span><br><span class="line"> a[u] = NINF;</span><br><span class="line"> <span class="keyword">if</span> (lb == rb) <span class="keyword">return</span>;</span><br><span class="line"> </span><br><span class="line"> build(l[u] = ++h, lb, (lb + rb) >> <span class="number">1</span>);</span><br><span class="line"> build(r[u] = ++h, (lb + rb) / <span class="number">2</span> + <span class="number">1</span>, rb); </span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">insert</span><span class="params">(<span class="keyword">int</span> u, <span class="keyword">int</span> lb, <span class="keyword">int</span> rb, <span class="keyword">int</span> pos, LL val)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (lb == rb) {</span><br><span class="line"> a[u] = val; <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> mid = (lb + rb) >> <span class="number">1</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (mid >= pos) {</span><br><span class="line"> insert(l[u], lb, mid, pos, val); </span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> insert(r[u], mid + <span class="number">1</span>, rb, pos, val); </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> a[u] = max(a[l[u]], a[r[u]]);</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function">LL <span class="title">query</span><span class="params">(<span class="keyword">int</span> u, <span class="keyword">int</span> lb, <span class="keyword">int</span> rb, <span class="keyword">int</span> lq, <span class="keyword">int</span> rq)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (lq <= lb && rb <= rq) {</span><br><span class="line"> <span class="keyword">return</span> a[u];</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (rb < lq || rq < lb) <span class="keyword">return</span> NINF;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> mid = (lb + rb) >> <span class="number">1</span>;</span><br><span class="line"> </span><br><span class="line"> LL a1 = query(l[u], lb, mid, lq, rq);</span><br><span class="line"> LL a2 = query(r[u], mid + <span class="number">1</span>, rb, lq, rq);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> max(a1, a2);</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="keyword">int</span> tx[<span class="number">2</span> * K], head;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">findX</span><span class="params">(<span class="keyword">int</span> val)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> low = <span class="number">1</span>, high = head;</span><br><span class="line"> <span class="keyword">int</span> res;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span> (low <= high) {</span><br><span class="line"> <span class="keyword">int</span> mid = (low + high) >> <span class="number">1</span>;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (tx[mid] <= val) {</span><br><span class="line"> low = mid + <span class="number">1</span>;</span><br><span class="line"> res = mid;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> high = 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 class="keyword">return</span> res;</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">solve</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &n, &q);</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, n) {</span><br><span class="line"> <span class="keyword">int</span> x, y, r;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>, &x, &y, &r);</span><br><span class="line"> p[i].x = x; p[i].y = y - r; p[i].r = r; </span><br><span class="line"> cx[i] = x;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, q) {</span><br><span class="line"> <span class="keyword">int</span> px, py, qx, qy, ymin, ymax;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d%d%d%d"</span>, &px, &py, &qx, &qy, &ymin, &ymax);</span><br><span class="line"> </span><br><span class="line"> cx[i + n] = px;</span><br><span class="line"> cx[i + n + q] = qx;</span><br><span class="line"> </span><br><span class="line"> qu[i].sx = min(px, qx);</span><br><span class="line"> qu[i].ex = max(px, qx);</span><br><span class="line"> qu[i].ymin = ymin;</span><br><span class="line"> qu[i].id = i;</span><br><span class="line"> qu[i].ymax = ymax;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> sort(p + <span class="number">1</span>, p + n + <span class="number">1</span>, cmpY);</span><br><span class="line"> sort(qu + <span class="number">1</span>, qu + q + <span class="number">1</span>, cmpQY);</span><br><span class="line"> sort(cx + <span class="number">1</span>, cx + n + <span class="number">2</span> * q + <span class="number">1</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> last;</span><br><span class="line"> FOE(i, <span class="number">1</span>, n + <span class="number">2</span> * q) {</span><br><span class="line"> <span class="keyword">if</span> (i == <span class="number">1</span> || cx[i] != last) {</span><br><span class="line"> head++; tx[head] = cx[i];</span><br><span class="line"> last = cx[i];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> build(<span class="number">0</span>, <span class="number">1</span>, head);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> ptr = <span class="number">1</span>;</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, q) {</span><br><span class="line"> <span class="keyword">int</span> cmin = qu[i].ymin;</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// printf("cmin is %d\n", cmin);</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span> (ptr <= n && p[ptr].y <= cmin) {</span><br><span class="line"> <span class="keyword">int</span> qx = findX(p[ptr].x);</span><br><span class="line"> <span class="comment">// printf("INSERT %d\n", ptr);</span></span><br><span class="line"> insert(<span class="number">0</span>, <span class="number">1</span>, head, qx, p[ptr].y + p[ptr].r * <span class="number">2</span>);</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// printf("PTR is %d\n", ptr);</span></span><br><span class="line"> </span><br><span class="line"> ptr++; </span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> qsx = findX(qu[i].sx);</span><br><span class="line"> <span class="keyword">int</span> qex = findX(qu[i].ex);</span><br><span class="line"> </span><br><span class="line"> <span class="comment">// printf("? %d %d\n", qsx, qex);</span></span><br><span class="line"> </span><br><span class="line"> <span class="keyword">int</span> id = qu[i].id;</span><br><span class="line"> </span><br><span class="line"> sol[id] = (query(<span class="number">0</span>, <span class="number">1</span>, head, qsx, qex) < qu[i].ymax);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> FOE(i, <span class="number">1</span>, q) {</span><br><span class="line"> <span class="keyword">if</span> (sol[i]) <span class="built_in">puts</span>(<span class="string">"YES"</span>); <span class="keyword">else</span> <span class="built_in">puts</span>(<span class="string">"NO"</span>); </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">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> solve();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="Problem-F-The-Halfwitters"><a href="#Problem-F-The-Halfwitters" class="headerlink" title="Problem F. The Halfwitters"></a>Problem F. The Halfwitters</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-F/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-F/</a></p>
<h2 id="Problem-G-Invited-Speakers"><a href="#Problem-G-Invited-Speakers" class="headerlink" title="Problem G. Invited Speakers"></a>Problem G. Invited Speakers</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-G/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-G/</a></p>
<h2 id="Problem-H-Lighthouses"><a href="#Problem-H-Lighthouses" class="headerlink" title="Problem H. Lighthouses"></a>Problem H. Lighthouses</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-H/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-H/</a></p>
<h2 id="Problem-I-Sum-of-Palindromes"><a href="#Problem-I-Sum-of-Palindromes" class="headerlink" title="Problem I. Sum of Palindromes"></a>Problem I. Sum of Palindromes</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-I/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-I/</a></p>
<h2 id="Problem-J-Space-Gophers"><a href="#Problem-J-Space-Gophers" class="headerlink" title="Problem J. Space Gophers"></a>Problem J. Space Gophers</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-J/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-J/</a></p>
<h2 id="Problem-K-To-argue-or-not-to-argue"><a href="#Problem-K-To-argue-or-not-to-argue" class="headerlink" title="Problem K. To argue, or not to argue"></a>Problem K. To argue, or not to argue</h2><p>大致题意:一个 $n \times m$ 的网格,某些位置是可用的(可以坐一个人),某些位置是不可用的(不能坐人)。现在有 $k$ 对共 $2k$ 个人,所有人两两不同。每个人都要坐到一个可用的位置,且每一对人坐的两个位置都不能相邻。问安排座位的方案数对 $10^9+7$ 取余后的结果。有 $z$ 组测试数据,数据保证可用的座位至少有 $2k$ 个。</p>
<p>$1 \leq z \leq 10$</p>
<p>$1 \leq n, m \leq 144$, $1 \leq k \leq \frac{nm}{2}$</p>
<h3 id="Solution-2"><a href="#Solution-2" class="headerlink" title="Solution"></a>Solution</h3><p>我读的题,第一反应是反过来统计有相邻的情况的方案数然后做个容斥。跟 clp012345 说了下题意,他说要再上个插头 DP。</p>
<p>事实证明这两个思路都是对的,但具体实现实在是太过复杂,我们在有更简单的题没写完的情况下也就放弃了,没继续往下讨论。</p>
<h2 id="Problem-L-Wizards-Unite"><a href="#Problem-L-Wizards-Unite" class="headerlink" title="Problem L. Wizards Unite"></a>Problem L. Wizards Unite</h2><p><a href="https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-L/">https://tanakarino.cn/2020/06/02/2020-Petrozavodsk-Winter-Camp-Day-5-L/</a></p>
]]></content>
<categories>
<category>_训练赛</category>
</categories>
</entry>
<entry>
<title>Meissel-Lehmer算法</title>
<url>/2020/06/02/Meissel-Lehmer%E7%AE%97%E6%B3%95/</url>
<content><![CDATA[<h1 id="引入"><a href="#引入" class="headerlink" title="引入"></a>引入</h1><p>首先引入一个问题。LibreOJ 6235:令 $\pi(n)$ 为 $n$ 以内的质数个数,求 $\pi(n)$ $(1 \leq n \leq 10^{11})$。</p>
<p>当然你可能会说你有分段打表的做法。众所周知,$1 \leq l \leq r \leq 10^{12}$ 且 $0 \leq r - l \leq 10^6$ 时,$[l, r]$ 中质数个数有一个很 trivial 的类似 Eratosthenes 筛的 $O((r - l)\log \log \sqrt r)$ 的做法。在这个基础上把 $[1, 10^{11}]$ 分成 $10^4$ 段,每段在本地预处理一下,段外的部分再单独算。这样分段打表确实可以卡过去,但是我们有不那么生草的做法:<del>洲阁筛</del> <del>min_25筛</del> Meissel-Lehmer 算法可以在 $O(n^{\frac23})$ 的时间复杂度内计算 $\pi(n)$。</p>
<p>这个算法在算法竞赛选手之间并不怎么普及(所以想写这篇文章),可能是因为实现起来确实略微有点麻烦(尤其是对不能抄板子的 OI 选手来说?)。虽然说 Miller-Rabin 素性判断和 Pollard-Rho 质因数分解也很麻烦,但也面对的场景大概也多一些,相比之下 Meissel-Lehmer 算法在算法竞赛生涯中可能遇不到几次(?)。目前见到的相关题目只有 2016 ICPC 沈阳赛区网络赛 J 和 2020 毛营 Day5 I,更生草的是可以看到后者的官方题解就是分段打表……大概进一步印证了这个算法的冷门……?</p>
<h1 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h1><p>令 $p_1, p_2, \dots, p_m$ 为前 $m$ 个质数。定义 $\phi(n, m)$ 为 $[1, n]$ 内所有质因子都大于 $p_m$ 的数的个数,$P_k(n, m)$ 为 $[1, n]$ 内恰有 $k$ 个大于 $p_m$ 的质因子的数的个数。 特别地,令 $P_0(n, m) = 1$,则有</p>
<script type="math/tex; mode=display">
\phi(n, m) = P_0(n, m) + P_1(n, m) + \dots + P_k(n, m) + \dots</script><p>注意到 $p_m^k > n$ 时有 $P_k(n, m) = 0$,所以,如果我们取 $x \in [n^{\frac13}, n^{\frac12}]$ 并令 $m = \pi(x)$,对于任意 $k \geq 3$,都有 $P_k(n, m) = 0$。即,</p>
<script type="math/tex; mode=display">
\phi(n, m) = P_0(n, m) + P_1(n, m) + P_2(n, m)</script><p>根据定义,显然 $P_1(n, m) = \pi(n) - m$,于是我们对上式适当变换,得</p>
<script type="math/tex; mode=display">
\pi(n) = \phi(n, m) - P_2(n, m) + m - 1</script><p>接下来,我们只需要计算 $\phi(n, m)$ 和 $P_2(n, m)$。根据定义,不难得到其计算方式如下:</p>
<script type="math/tex; mode=display">
P_2(n, m) = \sum_{x < p \leq \sqrt n} (\pi(\frac np) - \pi(p) + 1)</script><script type="math/tex; mode=display">
\phi(n, m) =
\begin{cases}
[n], & m = 0 \\
\phi(n, m - 1) - \phi(\frac {n}{p_m}, m - 1), & m \geq 1
\end{cases}</script><h1 id="复杂度分析"><a href="#复杂度分析" class="headerlink" title="复杂度分析"></a>复杂度分析</h1><h2 id="P-2-n-m"><a href="#P-2-n-m" class="headerlink" title="$P_2(n, m)$"></a>$P_2(n, m)$</h2><p>对于 $x < p \leq \sqrt n$,显然有 $\frac np < \frac nx < n^{\frac 23}$,为了快速计算 $P_2(n, m)$,我们可以用线性筛 $O(n^\frac 23)$ 预处理 $[1, n^{\frac 23}]$ 内的质数,然后 $O(n^\frac 12)$ 进行累加。时间复杂度 $O(n^\frac 23)$,空间复杂度 $O(n^\frac 23)$。</p>
<p>如果这个空间复杂度无法接受,我们可以时间换空间,少预处理一些,对于较大的询问则令 $\pi(n)$ 和 $P_2(n, m)$ 相互调用。那么时空复杂度是多少,究竟应该预处理多少呢?下面那份网上找的板子预处理的范围是 $5 \times 10^6$,并且认为可以降到 $n^\frac 13$,我暂且没算明白……</p>
<h2 id="phi-n-m"><a href="#phi-n-m" class="headerlink" title="$\phi(n, m)$"></a>$\phi(n, m)$</h2><p>更算不明白了……这式子看上去挺慢的,然而又可以大力预处理大力剪枝(见板子),总之实际跑起来完全没问题。但很想知道时间复杂度怎么算……</p>
<h1 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h1><p>这是网上可以大量找到的一个 Meissel-Lehmer 的板子(看码风也知道不是我写的),想自己整一个,但是我太懒了。</p>
<figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">5e6</span> + <span class="number">2</span>;<span class="comment">//通过知道前面的n^1/3的质数可以推断后面n^2/3的质数所以可以适当减小</span></span><br><span class="line"><span class="keyword">bool</span> np[N];</span><br><span class="line"><span class="keyword">int</span> prime[N], pi[N];</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">getprime</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> cnt = <span class="number">0</span>;</span><br><span class="line"> np[<span class="number">0</span>] = np[<span class="number">1</span>] = <span class="literal">true</span>;</span><br><span class="line"> pi[<span class="number">0</span>] = pi[<span class="number">1</span>] = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">2</span>; i < N; ++i)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(!np[i]) prime[++cnt] = i;</span><br><span class="line"> pi[i] = cnt;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">1</span>; j <= cnt && i * prime[j] < N; ++j)</span><br><span class="line"> {</span><br><span class="line"> np[i * prime[j]] = <span class="literal">true</span>;</span><br><span class="line"> <span class="keyword">if</span>(i % prime[j] == <span class="number">0</span>) <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> cnt;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> M = <span class="number">7</span>;<span class="comment">//为了减小内存可以不过是质数</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> PM = <span class="number">2</span> * <span class="number">3</span> * <span class="number">5</span> * <span class="number">7</span> * <span class="number">11</span> * <span class="number">13</span> * <span class="number">17</span>;<span class="comment">//为了减小内存可以不过要按质数减小如去掉17</span></span><br><span class="line"><span class="keyword">int</span> phi[PM + <span class="number">1</span>][M + <span class="number">1</span>], sz[M + <span class="number">1</span>];</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">init</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> getprime();</span><br><span class="line"> sz[<span class="number">0</span>] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">0</span>; i <= PM; ++i) phi[i][<span class="number">0</span>] = i;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = <span class="number">1</span>; i <= M; ++i)</span><br><span class="line"> {</span><br><span class="line"> sz[i] = prime[i] * sz[i - <span class="number">1</span>];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j = <span class="number">1</span>; j <= PM; ++j) phi[j][i] = phi[j][i - <span class="number">1</span>] - phi[j / prime[i]][i - <span class="number">1</span>];</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">sqrt2</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> ll r = (ll)<span class="built_in">sqrt</span>(x - <span class="number">0.1</span>);</span><br><span class="line"> <span class="keyword">while</span>(r * r <= x) ++r;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">int</span>(r - <span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">sqrt3</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> ll r = (ll)cbrt(x - <span class="number">0.1</span>);</span><br><span class="line"> <span class="keyword">while</span>(r * r * r <= x) ++r;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">int</span>(r - <span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">getphi</span><span class="params">(ll x, <span class="keyword">int</span> s)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(s == <span class="number">0</span>) <span class="keyword">return</span> x;</span><br><span class="line"> <span class="keyword">if</span>(s <= M) <span class="keyword">return</span> phi[x % sz[s]][s] + (x / sz[s]) * phi[sz[s]][s];</span><br><span class="line"> <span class="keyword">if</span>(x <= prime[s]*prime[s]) <span class="keyword">return</span> pi[x] - s + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(x <= prime[s]*prime[s]*prime[s] && x < N)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> s2x = pi[sqrt2(x)];</span><br><span class="line"> ll ans = pi[x] - (s2x + s - <span class="number">2</span>) * (s2x - s + <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = s + <span class="number">1</span>; i <= s2x; ++i) ans += pi[x / prime[i]];</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> getphi(x, s - <span class="number">1</span>) - getphi(x / prime[s], s - <span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">getpi</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(x < N) <span class="keyword">return</span> pi[x];</span><br><span class="line"> ll ans = getphi(x, pi[sqrt3(x)]) + pi[sqrt3(x)] - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i = pi[sqrt3(x)] + <span class="number">1</span>, ed = pi[sqrt2(x)]; i <= ed; ++i) ans -= getpi(x / prime[i]) - i + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">lehmer_pi</span><span class="params">(ll x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(x < N) <span class="keyword">return</span> pi[x];</span><br><span class="line"> <span class="keyword">int</span> a = (<span class="keyword">int</span>)lehmer_pi(sqrt2(sqrt2(x)));</span><br><span class="line"> <span class="keyword">int</span> b = (<span class="keyword">int</span>)lehmer_pi(sqrt2(x));</span><br><span class="line"> <span class="keyword">int</span> c = (<span class="keyword">int</span>)lehmer_pi(sqrt3(x));</span><br><span class="line"> ll sum = getphi(x, a) +(ll)(b + a - <span class="number">2</span>) * (b - a + <span class="number">1</span>) / <span class="number">2</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = a + <span class="number">1</span>; i <= b; i++)</span><br><span class="line"> {</span><br><span class="line"> ll w = x / prime[i];</span><br><span class="line"> sum -= lehmer_pi(w);</span><br><span class="line"> <span class="keyword">if</span> (i > c) <span class="keyword">continue</span>;</span><br><span class="line"> ll lim = lehmer_pi(sqrt2(w));</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = i; j <= lim; j++) sum -= lehmer_pi(w / prime[j]) - (j - <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> sum;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>这个板子有一个比较有疑问的地方:有两个功能完全一样的函数 <code>getpi</code> 和 <code>lehmer_pi</code>。很显然 <code>getpi</code> 就是我们上面介绍的方法,但 <code>lehmer_pi</code> 写的内容我完全没懂……看起来是传说中(?)Deleglise 和 Rivat 提出的 $O(\frac{n^\frac 23}{\log^2 n})$ 的优化(有兴趣可以看<a href="https://www.ams.org/journals/mcom/1996-65-213/S0025-5718-96-00674-6/S0025-5718-96-00674-6.pdf" target="_blank" rel="noopener">这篇论文</a>)。如果真的是的话,只能说这个优化的常数也太大了——测试了各种数据范围,结论是这个 <code>lehmer_pi</code> 跑起来比 <code>getpi</code> 还要慢一些……如果要抄这个板子的话,还是直接忽略最后一段吧……</p>
]]></content>
<categories>
<category>数论</category>
<category>整除与同余</category>
</categories>
<tags>
<tag>Meissel-Lehmer算法</tag>
</tags>
</entry>
<entry>
<title>2020 CCPC-Wannafly Winter Camp Day 1 A</title>
<url>/2020/06/02/2020-CCPC-Wannafly-Winter-Camp-Day-1-A/</url>
<content><![CDATA[<h1 id="Problem-A-期望逆序对"><a href="#Problem-A-期望逆序对" class="headerlink" title="Problem A. 期望逆序对"></a>Problem A. 期望逆序对</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给 $n$ 个随机变量 $x_1,x_2,\dots,x_n$,$x_i$ 的值是 $[l_i,r_i]$ 中随机选取的整数。你可以将这些随机变量排成任意的顺序,求逆序对数期望的最小值对 $998244353$ 取余后的结果。</p>
<p>$1 \leq n \leq 5 \times 10^3$, $1 \leq l_i \leq r_i \leq 10^9$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>事实上,取值的期望(即 $\frac{l_i+r_i}{2}$)越小就应该排在越前面,这样得到的序列的逆序对数的期望就是最小的。</p>
<p>为什么呢?对于任意一个序列,我们选择相邻的两项,其他项不动,考虑这两项是否应该交换。如果前一项的期望比后一项大,那么显然交换之后逆序对数减小,所以答案的序列中相邻里两项一定是前一项的期望比较小,而要满足这个性质就只能令期望单增,于是我们确定了这个序列的顺序。</p>
<p>之后就只需要 $O(n^2)$ 枚举每一对变量,$O(1)$ 计算其产生的逆序对数就行了。把两个变量看成分别在 $x$ 轴和 $y$ 轴上的区间,两个变量之间能产生的逆序对数其实就等价于一个矩形在 $y=x$ 的一侧的面积吧,这个就各凭本事吧,现场写的是分类讨论。</p>
<h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">1e5</span> + <span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> M = <span class="number">1e3</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod = <span class="number">998244353</span>;</span><br><span class="line"></span><br><span class="line"><span class="function">ll <span class="title">qpow</span> <span class="params">(ll a, ll b)</span> </span>{</span><br><span class="line"> ll ret = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> (b) {</span><br><span class="line"> <span class="keyword">if</span> (b & <span class="number">1</span>) ret = ret * a % mod;</span><br><span class="line"> a = a * a % mod;</span><br><span class="line"> b >>= <span class="number">1</span>;</span><br><span class="line"> }</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">ll <span class="title">inv</span> <span class="params">(ll a)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> qpow(a, mod - <span class="number">2</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">node</span> {</span></span><br><span class="line"> <span class="keyword">int</span> l, r;</span><br><span class="line">} a[N];</span><br><span class="line">ll invv[N];</span><br><span class="line"><span class="keyword">bool</span> <span class="keyword">operator</span> < (<span class="keyword">const</span> node& a, <span class="keyword">const</span> node& b) {</span><br><span class="line"> <span class="keyword">return</span> a.l + a.r < b.l + b.r;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">ll <span class="title">calc</span> <span class="params">(<span class="keyword">const</span> node& a, <span class="keyword">const</span> node& b)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (a.l <= b.l) {</span><br><span class="line"> <span class="keyword">if</span> (a.r <= b.l) <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> ((a.r > b.l) && (a.r <= b.r)) {</span><br><span class="line"> ll tmp = a.r - b.l + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> tmp * (tmp - <span class="number">1</span>) / <span class="number">2</span> % mod;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> (a.r > b.r) {</span><br><span class="line"> ll tmp = (b.r - b.l + <span class="number">1</span>);</span><br><span class="line"> ll sum = tmp * (tmp - <span class="number">1</span>) / <span class="number">2</span> % mod;</span><br><span class="line"> sum += (a.r - b.r) * tmp;</span><br><span class="line"> <span class="keyword">return</span> sum % mod;</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> ll tmp = (a.r - a.l + <span class="number">1</span>);</span><br><span class="line"> ll sum = tmp * (tmp - <span class="number">1</span>) / <span class="number">2</span> % mod;</span><br><span class="line"> sum += (a.l - b.l) * tmp;</span><br><span class="line"> <span class="keyword">return</span> sum % mod;</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">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &n);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &a[i].l, &a[i].r);</span><br><span class="line"> }</span><br><span class="line"> sort(a + <span class="number">1</span>, a + n + <span class="number">1</span>);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> invv[i] = inv(a[i].r - a[i].l + <span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> ll q = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> q *= a[i].r - a[i].l + <span class="number">1</span>;</span><br><span class="line"> q %= mod;</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> ll p = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = i + <span class="number">1</span>;j <= n;j++) {</span><br><span class="line"> ll tmp = calc(a[i], a[j]);</span><br><span class="line"> tmp = tmp * invv[i] % mod;</span><br><span class="line"> tmp = tmp * invv[j] % mod;</span><br><span class="line"> p += tmp;</span><br><span class="line"> <span class="keyword">if</span> (p >= mod) p -= mod;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld"</span>, p);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>基础算法</category>
<category>贪心</category>
</categories>
<tags>
<tag>贪心</tag>
</tags>
</entry>
<entry>
<title>2020 CCPC-Wannafly Winter Camp Day 1 C</title>
<url>/2020/06/02/2020-CCPC-Wannafly-Winter-Camp-Day-1-C/</url>
<content><![CDATA[<h1 id="Problem-C-染色图"><a href="#Problem-C-染色图" class="headerlink" title="Problem C. 染色图"></a>Problem C. 染色图</h1><p><del>色图?哪里有色图?</del></p>
<h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>在一张无向图中,如果存在一种方案,使得给每个结点染上一种颜色 $c_i \in [1,k]$ 后,任意一对相邻结点的颜色不同,则称这张无向图可以 $k$ 染色。在有 $n$ 个节点的、可以 $k$ 染色的所有简单图中,选出边数最多的一个,我们记其边数为 $g(n,k)$。</p>
<p>现在,给定 $n,l,r$,求 $\sum_{i=l}^{r} g(n,i)$ 对 $998244353$ 取余后的结果。有 $T$ 组测试数据。</p>
<p>$1 \leq T \leq 1000$</p>
<p>$1 \leq l \leq r \leq n \leq 10^9$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>考虑一张有 $n$ 个结点染上 $k$ 种颜色,每种颜色使用了 $a_i$ 次。既然只有同色是不能连边的,那么我们把除了同色的团只玩的边全部连起来。一个大小为 $x$ 的团有 $\frac{x(x+1)}2$ 条边,那么总边数应该是</p>
<script type="math/tex; mode=display">
\binom{n}{2} -
\sum_{i=1}^{k} \binom{a_i}{2}</script><p>不难发现,要最大化总边数其实也就是要最小化 $\sum_{i=1}^k a_i^2$。为满足这一点,$a_i$ 应当均分。如果 $a_i$ 不是均分,即存在 $i,j$ 使得 $|a_i-a_j| \geq 2$,那么令 $a_i = a_j = \frac{a_i+a_j}{2}$,$\sum_{i=1}^k a_i^2$ 显然变小。所以,$a_i$ 肯定是均分,即有 $n \bmod k$ 个 $a_i$ 等于 $\lfloor \frac nk \rfloor + 1$,剩下的 $k - n \bmod k$ 个 $a_i$ 等于 $\lfloor \frac nk \rfloor$。</p>
<p>又考虑到 $n \bmod k$ 其实就等于 $n - k\lfloor \frac nk \rfloor$,所以,我们得出一个很长很长的式子</p>
<script type="math/tex; mode=display">
g(n, k) = \binom {n}{2}
-
(n - k\lfloor \frac nk \rfloor) \cdot \binom {\lfloor \frac nk \rfloor + 1} {2}
-
(k - n + k\lfloor \frac nk \rfloor) \cdot \binom {\lfloor \frac nk \rfloor} {2}</script><p>队友 Luowaterbi 化简了很久很久,结果好像是</p>
<script type="math/tex; mode=display">
g(n, k) = \frac 12
(
n^2 - n -
2n \lfloor \frac nk \rfloor +
k \lfloor \frac nk \rfloor +
k \lfloor \frac nk \rfloor ^ 2
)</script><p><del>太久远了我也不知道是不是对的建议自己化简一遍</del></p>
<p>然后大力往上套数论分块就过辣!时间复杂度 $O(T \sqrt n)$。</p>
<h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">1e5</span> + <span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> M = <span class="number">1e3</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod = <span class="number">998244353</span>;</span><br><span class="line"></span><br><span class="line"><span class="function">ll <span class="title">qpow</span> <span class="params">(ll a, ll b)</span> </span>{</span><br><span class="line"> ll ret = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span> (b) {</span><br><span class="line"> <span class="keyword">if</span> (b & <span class="number">1</span>) ret = ret * a % mod;</span><br><span class="line"> a = a * a % mod;</span><br><span class="line"> b >>= <span class="number">1</span>;</span><br><span class="line"> }</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">ll <span class="title">inv</span> <span class="params">(ll a)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> qpow(a, mod - <span class="number">2</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> T;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &T);</span><br><span class="line"> <span class="keyword">while</span> (T--) {</span><br><span class="line"> ll n, l0, r0;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld%lld%lld"</span>, &n, &l0, &r0);</span><br><span class="line"> ll ans = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> l = l0, r;l <= r0;l = r + <span class="number">1</span>) {</span><br><span class="line"> ll k = n / l;</span><br><span class="line"> r = min(n / k, r0);</span><br><span class="line"> ll len = r - l + <span class="number">1</span>;</span><br><span class="line"> ll cur = <span class="number">0</span>;</span><br><span class="line"> cur += (n * n - n) % mod * len % mod;</span><br><span class="line"> cur -= <span class="number">2</span> * n * len % mod * k % mod;</span><br><span class="line"> cur += ((l + r) * len / <span class="number">2</span>) % mod * k % mod;</span><br><span class="line"> cur += ((l + r) * len / <span class="number">2</span>) % mod * k % mod * k % mod;</span><br><span class="line"> cur = (cur % mod + mod) % mod;</span><br><span class="line"> ans = (ans + cur) % mod;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>, ans * inv(<span class="number">2</span>) % mod);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数论</category>
<category>数论分块</category>
</categories>
<tags>
<tag>数论分块</tag>
</tags>
</entry>
<entry>
<title>2020 CCPC-Wannafly Winter Camp Day 1 B</title>
<url>/2020/06/02/2020-CCPC-Wannafly-Winter-Camp-Day-1-B/</url>
<content><![CDATA[<h1 id="Problem-B-密码学"><a href="#Problem-B-密码学" class="headerlink" title="Problem B. 密码学"></a>Problem B. 密码学</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>将小写字母从 $0$ 到 $25$ 编号,将大写字母从 $26$ 到 $51$ 编号。用字符 $a$ 加密字符 $b$ 得到的字符,是 $a$ 和 $b$ 的编号相加后对 $52$ 取余后的结果对应的字符。用字符串 $key$ 加密字符串 $s$ 得到的字符串长度与 $s$ 相同,其中,第 $i$ 个字符是用 $key_i$ 加密 $s_i$ 得到的字符,如果 $key$ 的长度不够,则将 $key$ 重复多次。</p>
<p>有 $n$ 个字符串 $s_1,s_2,\dots,s_n$ 和 $m$ 次加密操作 $(x_1,y_1),(x_2,y_2),\dots,(x_n,y_n)$。第 $i$ 次加密操作用 $s_{x_i}$ 加密 $s_{y_i}$,并将 $s_{y_i}$ 替换为加密结果。现在给出 $n$ 个字符串的最终结果和 $m$ 次加密操作,求 $n$ 个字符串的初始值。</p>
<p>$1 \leq n,m \leq 1000$, $1 \leq x_i,y_i \leq n$</p>
<p>$1 \leq |s_i| \leq 100$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>模拟题,没啥好说的……加密是加解密就是减……</p>
<h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">1e5</span> + <span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> x[N], y[N];</span><br><span class="line"><span class="keyword">char</span> s[N][<span class="number">105</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">chartoint</span> <span class="params">(<span class="keyword">char</span> c)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> ((<span class="string">'a'</span> <= c) && (c <= <span class="string">'z'</span>)) <span class="keyword">return</span> c - <span class="string">'a'</span>;</span><br><span class="line"> <span class="keyword">if</span> ((<span class="string">'A'</span> <= c) && (c <= <span class="string">'Z'</span>)) <span class="keyword">return</span> c - <span class="string">'A'</span> + <span class="number">26</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">char</span> <span class="title">inttochar</span> <span class="params">(<span class="keyword">int</span> a)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> ((<span class="number">0</span> <= a) && (a <= <span class="number">25</span>)) <span class="keyword">return</span> a + <span class="string">'a'</span>;</span><br><span class="line"> <span class="keyword">if</span> ((<span class="number">26</span> <= a) && (a <= <span class="number">51</span>)) <span class="keyword">return</span> a - <span class="number">26</span> + <span class="string">'A'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> n, m;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &n, &m);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= m;i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>, &x[i], &y[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>, &s[i]);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = m;i >= <span class="number">1</span>;i--) {</span><br><span class="line"> <span class="keyword">int</span> lx = <span class="built_in">strlen</span>(s[x[i]]);</span><br><span class="line"> <span class="keyword">int</span> ly = <span class="built_in">strlen</span>(s[y[i]]);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">0</span>;j < ly;j++) {</span><br><span class="line"> <span class="keyword">int</span> tmp = <span class="number">0</span>;</span><br><span class="line"> tmp += chartoint(s[y[i]][j]);</span><br><span class="line"> tmp -= chartoint(s[x[i]][j % lx]);</span><br><span class="line"> tmp += <span class="number">52</span>;</span><br><span class="line"> tmp %= <span class="number">52</span>;</span><br><span class="line"> s[y[i]][j] = inttochar(tmp);</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">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%s\n"</span>, s[i]);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>基础算法</category>
<category>模拟</category>
</categories>
<tags>
<tag>模拟</tag>
</tags>
</entry>
<entry>
<title>2020 CCPC-Wannafly Winter Camp Day 1 F</title>
<url>/2020/06/02/2020-CCPC-Wannafly-Winter-Camp-Day-1-F/</url>
<content><![CDATA[<h1 id="Problem-F-乘法"><a href="#Problem-F-乘法" class="headerlink" title="Problem F. 乘法"></a>Problem F. 乘法</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给两个长度分别为 $n,m$ 的数列 $A, B$ 来表示一个 $n \times m$ 的矩阵 $C$(即 $C_{i,j} = A_i \cdot B_j$)。 给出整数 $K$,你需要求出 $C$ 中第 $K$ 大的数。</p>
<p>$1 \leq n,m \leq 10^5$, $1 \leq K \leq n \times m$</p>
<p>$-10^6 \leq A_i,B_i \leq 10^6$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>$O(n \log m \log (\max C_{i,j} - \min C_{i,j}))$ 的做法显然吧……</p>
<p>我们预先对每一行排好序。对于一个假定的答案 $mid$,我们可以 $O(n)$ 枚举行,对于每一行都 $O(\log m)$ 二分一下计算有多少个数大于 $mid$,就能 $O(n \log m)$ 计算 $mid$ 是第几大。又因为 $mid$ 与其位次是单调的关系,那么考虑二分答案 $mid$,就可以 $O(n \log m \log (\max C_{i,j} - \min C_{i,j}))$ 求 $K$ 大了。</p>
<p>二分这种东西需要注意一下细节,尤其是这题还有负数和 $0$……我开场读的第一题就是这个,一眼就会了,以为有希望抢一血,结果是被 <code>lower_bound</code> 和 <code>upper_bound</code> 演了很久,调了一个小时……太丢人了……</p>
<h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">1e5</span> + <span class="number">5</span>;</span><br><span class="line">ll a[N], b[N];</span><br><span class="line">ll n, m, k;</span><br><span class="line"></span><br><span class="line"><span class="function">ll <span class="title">getrank</span> <span class="params">(ll cur)</span> </span>{</span><br><span class="line"> ll rank = <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> ll pos;</span><br><span class="line"> <span class="keyword">if</span> (a[i] == <span class="number">0</span>) pos = (cur <= <span class="number">0</span>) ? m : <span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span> (a[i] > <span class="number">0</span>) pos = m - (lower_bound(b + <span class="number">1</span>, b + m + <span class="number">1</span>, (<span class="keyword">double</span>)cur / a[i]) - (b + <span class="number">1</span>));</span><br><span class="line"> <span class="keyword">if</span> (a[i] < <span class="number">0</span>) pos = upper_bound(b + <span class="number">1</span>, b + m + <span class="number">1</span>, (<span class="keyword">double</span>)cur / a[i]) - (b + <span class="number">1</span>);</span><br><span class="line"> rank += pos;</span><br><span class="line"> <span class="comment">//cout << "L" << i << ':' << pos << endl;</span></span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> rank + <span class="number">1</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld%lld%lld"</span>, &n, &m, &k);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= n;i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld"</span>, &a[i]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">1</span>;i <= m;i++) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld"</span>, &b[i]);</span><br><span class="line"> }</span><br><span class="line"> sort(b + <span class="number">1</span>, b + m + <span class="number">1</span>);</span><br><span class="line"> </span><br><span class="line"> ll l = <span class="number">-1e12</span>, r = <span class="number">1e12</span>;</span><br><span class="line"> <span class="keyword">while</span> (l <= r) {</span><br><span class="line"> ll mid = (l + r) / <span class="number">2</span>;</span><br><span class="line"> ll rank = getrank(mid);</span><br><span class="line"> <span class="keyword">if</span> (rank > k) l = mid + <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> r = mid - <span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld"</span>, r);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>基本算法</category>
<category>二分答案</category>
</categories>
<tags>
<tag>二分答案</tag>
<tag>二分</tag>
</tags>
</entry>
<entry>
<title>2020 CCPC-Wannafly Winter Camp Day 1 H</title>
<url>/2020/06/02/2020-CCPC-Wannafly-Winter-Camp-Day-1-H/</url>
<content><![CDATA[<h1 id="Problem-H-最大公约数"><a href="#Problem-H-最大公约数" class="headerlink" title="Problem H. 最大公约数"></a>Problem H. 最大公约数</h1><h2 id="Statement"><a href="#Statement" class="headerlink" title="Statement"></a>Statement</h2><p>给出两个整数 $k,n$ ($1 \leq k \leq n$),求最小的 $y$,使得对于任意 $x \in [1,n]$ 且 $x \neq k$,都满足 $\gcd(x, y) \neq \gcd(k,y)$。如果不存在这样的 $y$,输出$-1$。有 $T$ 组测试数据。</p>
<p>$1 \leq T \leq 50$</p>
<p>$1 \leq k \leq n \leq 500$</p>
<h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>不存在这样的 $y$ 当然是骗你的,因为一定存在……</p>
<p>我在狂演 F 题的时候这题就有一些队伍过了,于是 Luowaterbi 和 owojiecao 就在看,但是没什么结论……我演完 F 之后看了一会<del>样例</del>,猜想答案就是 $k \cdot \prod_{i = 1, i \in p}^{\lfloor \frac{n}{k} \rfloor} i$,虽然不会证明但是我们三个都没想到反例,于是我就交了两发 WA,发现需要高精度,用 Java 重写,过了。</p>
<p><del>抄了一个</del>必要性证明大概是这样的:</p>
<ul>
<li>必须保证 $k|y$。否则就有 $\gcd(k,y) \neq k$,又因为显然 $\gcd(k,y) = \gcd(\gcd(k,y),y)$,就不符合题意了啊。</li>
<li>对于 $[1,\lfloor \frac nk \rfloor]$ 中的每一个质数 $p$,必须保证 $p|\frac yk$。否则就有 $\gcd(pk,y) = k \cdot \gcd(p,y/k) = k =\gcd(k,y)$,就不符合题意了啊。</li>
</ul>
<p>充分性问就是不会证啊,proof by AC。</p>
<h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><p>这是不带高精度 WA 掉的版本。</p>
<figure class="highlight c++"><table><tr><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N = <span class="number">1e5</span> + <span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> M = <span class="number">1e3</span>;</span><br><span class="line"></span><br><span class="line">ll flag[N], pri[N];</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">sieve</span> <span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">2</span>;i < M;i++) {</span><br><span class="line"> <span class="keyword">if</span> (!flag[i])</span><br><span class="line"> pri[++pri[<span class="number">0</span>]] = i;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">1</span>;j <= pri[<span class="number">0</span>] && pri[j] * i < M;j++) {</span><br><span class="line"> flag[pri[j] * i] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (i % pri[j] == <span class="number">0</span>) <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><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span> <span class="params">()</span> </span>{</span><br><span class="line"> sieve();</span><br><span class="line"> <span class="keyword">int</span> T;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>, &T);</span><br><span class="line"> <span class="keyword">while</span> (T--) {</span><br><span class="line"> ll n, k;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld%lld"</span>, &n, &k);</span><br><span class="line"> ll p = <span class="number">1</span>, ans = k;</span><br><span class="line"> <span class="keyword">while</span> (k * pri[p] <= n) {</span><br><span class="line"> ans *= pri[p];</span><br><span class="line"> p++;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>, ans);</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>
<p>这是带高精度的 Java 版本。我实在是不会 Java,勉强照着上面的 C++ 打的,如果写得很傻逼请不要 D 我呜呜呜</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">import</span> java.math.BigInteger;</span><br><span class="line"><span class="keyword">import</span> java.util.Scanner;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span> <span class="params">(String args[])</span> </span>{</span><br><span class="line"> <span class="keyword">final</span> <span class="keyword">int</span> N = <span class="number">1000</span>;</span><br><span class="line"> <span class="keyword">int</span> flag[] = <span class="keyword">new</span> <span class="keyword">int</span>[N];</span><br><span class="line"> <span class="keyword">int</span> pri[] = <span class="keyword">new</span> <span class="keyword">int</span>[N];</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">2</span>;i < N;i++) {</span><br><span class="line"> <span class="keyword">if</span> (flag[i] == <span class="number">0</span>) pri[++pri[<span class="number">0</span>]] = i;</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> j = <span class="number">1</span>;j <= pri[<span class="number">0</span>] && i * pri[j] < N;j++) {</span><br><span class="line"> flag[i * pri[j]] = <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (i % pri[j] == <span class="number">0</span>) <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"> Scanner scan = <span class="keyword">new</span> Scanner(System.in);</span><br><span class="line"> <span class="keyword">int</span> T = scan.nextInt();</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> it = <span class="number">1</span>;it <= T;it++) {</span><br><span class="line"> <span class="keyword">int</span> n = scan.nextInt();</span><br><span class="line"> <span class="keyword">int</span> k = scan.nextInt();</span><br><span class="line"> <span class="keyword">int</span> p = <span class="number">1</span>;</span><br><span class="line"> BigInteger ans = <span class="keyword">new</span> BigInteger(k + <span class="string">""</span>);</span><br><span class="line"> <span class="keyword">while</span> (k * pri[p] <= n) {</span><br><span class="line"> ans = ans.multiply(BigInteger.valueOf(pri[p]));</span><br><span class="line"> p++;</span><br><span class="line"> }</span><br><span class="line"> System.out.println(ans);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数论</category>
<category>整除与同余</category>
</categories>
<tags>
<tag>高精度</tag>
<tag>结论/规律</tag>
<tag>欧拉筛</tag>
</tags>
</entry>
<entry>
<title>[20200607] 2018-2019 ACM-ICPC, Asia Qingdao Regional Contest</title>
<url>/2020/06/07/20200607-2018-2019-ACM-ICPC-Asia-Qingdao-Regional-Contest/</url>
<content><![CDATA[<h1 id="Review"><a href="#Review" class="headerlink" title="Review"></a>Review</h1><p>感觉还是好菜,该加训了……</p>
<p>刚开场就开始演队友。我直接读了 J,迅速大力交了两发 WA 的二分答案。一看 M 过了好多,又大力交了一发 WA。想了一会,才突然意识到 J 题的合法性并不是单调的,于是,Luowaterbi 认为答案就是一个前缀和加一个后缀 min,我照做,又交了一发 WA。</p>
<p>此时已经快一个小时了,而我们两个水题都 WA 着……我突然意识到 M 题需要特判 <code>0 1</code>,改了改过了,<strong>58min2A</strong>。owojiecao 突然发现 J 题 $0$ 必买,应该去掉 $0$ 再做。我和 Luowaterbi 纷纷感叹自己傻逼,然后我手抖写错,又交了两发才过,<strong>70min5A</strong>。此时发现 C 过题人数和 J 差不多,于是读 C,发现是个分类讨论傻逼题,然后我第一发没讨论没 $1$ 的情况,第二发交了个弱智 PE,第三发才过,<strong>84min3A</strong>。</p>
<p>我智商完全不在线,短短不到一个半小时的时间连交了七发罚时,已经同题数垫底 rank 105,感谢队友不杀之恩。</p>
<p>好在中期打得还不算烂。此时大多数人都是三题, DEF 都是刚有几个人通过。我读了 D,Luowaterbi 读了 F,无果,交换题意,我发现 F 是个找规律的构造题,手玩了一会之后会了,但没认真审题又交了一发 PE,<strong>142min2A</strong>,rank 上升到 43<del>,还是同题数垫底</del>。我们又读了难度跟 DF 相近的 E,我说二分答案显然,于是转化成询问给定步数之内能否访问每个位置给定次数。想了一会发现大力贪心似乎可行,但没处理好交了发 WA,遂下机交给 owojiecao 写 D。跟 luowaterbi 一起读了很久 E 的代码,改了三次,终于发现我有个地方写了点很弱智的东西……<strong>228min4A</strong>,rank 掉到 55<del>,还是同题数垫底(虽然之后有人帮我们垫底了)</del>。</p>
<p>接下来只有 owojiecao 的 D 比较可以期待的样子,而我和 Luowaterbi 去读剩下的题里读相对可能比较可做的 L。事实证明 L 是个我们之中并没有人会的生成函数,而 owojiecao 的 D 也没调出来……</p>
<p>最后 rank 80/354,什么时候能进个 Au 线呢……</p>
<h1 id="Solution(咕咕)"><a href="#Solution(咕咕)" class="headerlink" title="Solution(咕咕)"></a>Solution(咕咕)</h1>]]></content>
<categories>
<category>_训练赛</category>
</categories>
</entry>
<entry>
<title>[20200614] 2016-2017 ACM-ICPC, Asia Shenyang Regional Contest</title>
<url>/2020/07/20/20200614-2016-2017-ACM-ICPC-Asia-Shenyang-Regional-Contest/</url>
<content><![CDATA[<h1 id="Review"><a href="#Review" class="headerlink" title="Review"></a>Review</h1><p>开场 Luowaterbi 告诉我 I 是 sb 题,让输出四个数的和,然后我就直接 ull 冲了上去 WA 了一发,才发现最大值正好可以卡爆 ull……这种题意义何在啊!!!加了个特判过了,<strong>13min2A</strong>。然后看榜好像 K 也很签到,于是写了一下,<strong>22min1A</strong>,由于手速还可以所以 rank28。</p>
<p>接下来的 L 和 F 难度好像差不多,我们先读了 L,接着队友又去读 F 了。我对着 L 一顿口胡,最后突然想到正解才发现口胡的全是假的,于是交了一发过了,<strong>60min1A</strong>,rank 掉到 31。然后我们对着 F 一顿推,但是没啥好的结论。推着推着,Luowaterbi 突然告诉我这个 F 居然有某种奇妙深刻的递推关系。但是数据范围又要求高精度,<del>所以我又开始展示我的垃圾 Java 水平</del>,这么简单的代码写了好久,然后还连交了四发 WA,debug 了半天之后突然发现是因为文件创建在一个 package 里,所以 Intellij 自动在我的代码开头加了 package 我没发现……<strong>122min5A</strong> 之后 rank 又掉到 37,<del>又是同题数垫底了……实在是我队传统艺能……</del></p>
<p>接下来 G 和 M 难度好像也差不多,我们先读了 G,接着队友又去读 M 了。我对着 G 一顿口胡<del>,说这个就是基环内向森林啊,然后类似后缀数组一样倍增乱搞一下就能搞出来</del>。但是后缀数组我学得实在垃圾,只会抄板子,有点写不明白,然后我爬了。但是 Luowaterbi 就不一样了,他看了很久的 M,看着看着,Luowaterbi 突然告诉我这个 M 居然只跟每个位置的后继状态数有关。于是我迅速写了一下,<strong>287min1A</strong>,rank 又掉到 46 了,我只能爬。</p>
<p>总成绩是 5 - 605,rank 50/186。只能说是稳定发挥,但是什么时候能进个 Au 线呢……其实这场六题 + 手速就 Au 了,就是说其实还是有希望的吧……(?</p>
<h1 id="Solution(咕咕)"><a href="#Solution(咕咕)" class="headerlink" title="Solution(咕咕)"></a>Solution(咕咕)</h1>]]></content>
<categories>
<category>_训练赛</category>
</categories>
</entry>
<entry>
<title>[20200705] 2017-2018 CCPC, Qinhuangdao</title>
<url>/2020/07/20/20200705-2017-2018-CCPC-Qinhuangdao/</url>
<content><![CDATA[<h1 id="Review"><a href="#Review" class="headerlink" title="Review"></a>Review</h1><p>开场跟榜看 L,水题不讲,<strong>10min1A</strong>,rank10<del>(什么嘛我手速还挺快的)</del>。跟榜看 C,字符串分类讨论一下,<strong>33min1A</strong>,rank11<del>(什么嘛我手速还挺快的)</del>。跟榜看 E,还是字符串分类讨论一下,但是漏情况了交了发 WA……<strong>57min2A</strong>,rank18<del>(什么嘛我手速还挺快的)</del>。</p>
<p>到目前为止都还算顺利,但是接下来的 M 我们开始三人互演。首先我们发现安全的程度和到原点的距离有关,但是达到一定临界值之后就一样安全了。一开始我想当然设了个临界值 <code>lim = R - r</code>,WA 了之后我认真画了个图改成了 <code>lim = max(0, R - 2 * r)</code>,又 WA 了之后 Luowaterbi 认真画了个图告诉我是 <code>lim = max(0, 2 * r - R)</code>,又 WA 了之后我才发现其实这是小圆半径不同取值范围时的两种情况,所以改成 <code>lim = abs(R - 2 * r)</code> 就过了,<strong>109min6A</strong>,是的,这题交了六发才过,过的时候 rank 已经掉到 66 了。</p>
<p>A 很有趣,是个好题,讨论了一会之后离散化过掉了,<strong>184min2A</strong>。G 讨论了一会之后我发现是从高位到低位贪心,由于需要高精度用 Java 写了一下,不知道 BigInteger 怎么算的内存,交了好几发 MLE 才过,<strong>259min5A</strong>。</p>
<p>过完 A 和 过完 G 的时候 rank 都是 44,但是最后又掉到 54 / 254 了。什么时候能进个 Au 线呢……</p>
<h1 id="Solution(咕咕)"><a href="#Solution(咕咕)" class="headerlink" title="Solution(咕咕)"></a>Solution(咕咕)</h1>]]></content>
<categories>
<category>_训练赛</category>
</categories>
</entry>
</search>