-
Notifications
You must be signed in to change notification settings - Fork 1
/
atom.xml
673 lines (449 loc) · 288 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Siyuan's Blog</title>
<icon>https://www.gravatar.com/avatar/7f5c232e160bb21b4c009adb298fdcfa</icon>
<subtitle>你强归你强,我永不示弱!</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://hydingsy.github.io/"/>
<updated>2019-03-09T12:55:59.253Z</updated>
<id>http://hydingsy.github.io/</id>
<author>
<name>Siyuan</name>
<email>294873684@qq.com</email>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title><strong><font size="20">「公告」博客搬迁</font></strong></title>
<link href="http://hydingsy.github.io/articles/Announcement/"/>
<id>http://hydingsy.github.io/articles/Announcement/</id>
<published>2019-03-06T16:00:00.000Z</published>
<updated>2019-03-09T12:55:59.253Z</updated>
<content type="html"><![CDATA[<center><font size="5">新博客地址:<a href="http://orzsiyuan.com" target="_blank" rel="noopener">orzsiyuan.com</a></font></center><p><strong>Siyuan’s Blog</strong>已经从 <a href="https://hydingsy.github.io">hydingsy.github.io</a> / <a href="http://old.orzsiyuan.com" target="_blank" rel="noopener">old.orzsiyuan.com</a> 搬迁到 <a href="http://orzsiyuan.com" target="_blank" rel="noopener">orzsiyuan.com</a>。本博客仅作为副本保留在此(这意味着今后可能删除),这里的文章将会陆续搬运到新博客中。</p><p><del>换过友链的大佬们可以考虑换个域名啦!新博客也继续资瓷换友链!QAQ</del></p><p>新的博客使用 <a href="http://typecho.org/" target="_blank" rel="noopener">Typecho</a> 搭建,欢迎大家访问!</p><div align="right">Siyuan</div><div align="right">2019.03.07</div>]]></content>
<summary type="html">
<center><font size="5">新博客地址:<a href="http://orzsiyuan.com" target="_blank" rel="noopener">orzsiyuan.com</a></font></center>
<p><strong>Siy
</summary>
</entry>
<entry>
<title>「Codeforces 402E」Strictly Positive Matrix</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-402E-Strictly-Positive-Matrix/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-402E-Strictly-Positive-Matrix/</id>
<published>2019-03-01T16:00:00.000Z</published>
<updated>2019-03-02T03:25:14.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/402/problem/E" target="_blank" rel="noopener">Codeforces 402E</a></p></blockquote><p>你有一个 $n\times n$ 的矩阵 $a$。它满足如下性质:</p><ul><li>对于任意的 $i,j$($1\le i,j\le n$)都有 $a_{i,j}\ge 0$。</li><li>$\sum_{i=1}^n a_{i,i}=0$</li></ul><p>矩阵 $b$ 是严格正矩阵当且仅当对于任意的 $i,j$($1\le i,j\le n$)都有 $b_{i,j}>0$。</p><p>求是否存在整数 $k\ge 1$ 使得 $a^k$ 是一个严格正矩阵。</p><p>数据范围:$2\le n\le 2\times 10^3$,$0\le a_{i,j}\le 50$,$\sum_{i=1}^n a_{i,i}=0$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>首先我们把这个矩阵转化为 $01$ 矩阵,它的 $k$ 次方代表着对它进行 $k$ 次迭代,得到的矩阵记为 $a’$。那么$a’_{i,j}=1$ 当且仅当<strong>邻接矩阵</strong> $a$ 形成的图中 $i$ 到 $j$ 有一条长度为 $k$ 的路径(并非是简单路径),也就是走 $k$ 次后图的连通性。</p><p>这样一来,我们把矩阵问题转化为图论问题了!</p><p>再观察这个问题的性质:由于对角线的和不为 $0$,那么存在至少一个点有<strong>自环</strong>。如果从 $i$ 到 $j$ 存在一条长度为 $k$ 且经过有自环的点,那么我们一定通过不断走自环可以得到长度为 $k+1,k+2,\dots$ 的路径。</p><p>这就意味着如果存在 $k$,那么一定<strong>所有点都可达</strong>。</p><p>直接用 $01$ 矩阵建立有向图,使用 $\text{Tarjan}$ 求出<strong>强连通分量</strong>的个数是否为 $1$ 即可。</p><p><strong>时间复杂度</strong>:$O(n^2)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><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">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"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> fail puts(<span class="meta-string">"NO"</span>),exit(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">2e3</span>+<span class="number">5</span>,M=N*N;</span><br><span class="line"><span class="keyword">int</span> n,idx,cnt,tot,lnk[N],ter[M],nxt[M],dfn[N],low[N];</span><br><span class="line"><span class="keyword">bool</span> vis[N];</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">stack</span><<span class="keyword">int</span>> st;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> v)</span> </span>{</span><br><span class="line"> ter[++tot]=v,nxt[tot]=lnk[u],lnk[u]=tot;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">tarjan</span><span class="params">(<span class="keyword">int</span> u)</span> </span>{</span><br><span class="line"> dfn[u]=low[u]=++idx,st.push(u),vis[u]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(!dfn[v]) {</span><br><span class="line"> tarjan(v);</span><br><span class="line"> low[u]=<span class="built_in">std</span>::min(low[u],low[v]);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span>(vis[v]) low[u]=<span class="built_in">std</span>::min(low[u],dfn[v]);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(dfn[u]==low[u]) {</span><br><span class="line"> <span class="keyword">if</span>(++cnt><span class="number">1</span>) fail;</span><br><span class="line"> <span class="keyword">do</span> {</span><br><span class="line"> vis[u=st.top()]=<span class="number">0</span>,st.pop();</span><br><span class="line"> } <span class="keyword">while</span>(dfn[u]!=low[u]);</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">"%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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) {</span><br><span class="line"> <span class="keyword">int</span> x;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&x);</span><br><span class="line"> <span class="keyword">if</span>(x&&i!=j) add(i,j);</span><br><span class="line"> }</span><br><span class="line"> tarjan(<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 class="keyword">if</span>(!dfn[i]) fail;</span><br><span class="line"> <span class="built_in">puts</span>(<span class="string">"YES"</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/402/problem/E" target="_blank" rel="noopener">Codeforces 402E</a></p>
</blockquote>
<p>你有一个 $n\times n$ 的矩阵 $a$。它满足如下性质:</p>
<ul>
<li>对于任意的 $i,j$($1\le i,j\le n$)都有 $a_{i,j}\ge 0$。</li>
<li>$\sum_{i=1}^n a_{i,i}=0$</li>
</ul>
<p>矩阵 $b$ 是严格正矩阵当且仅当对于任意的 $i,j$($1\le i,j\le n$)都有 $b_{i,j}&gt;0$。</p>
<p>求是否存在整数 $k\ge 1$ 使得 $a^k$ 是一个严格正矩阵。</p>
<p>数据范围:$2\le n\le 2\times 10^3$,$0\le a_{i,j}\le 50$,$\sum_{i=1}^n a_{i,i}=0$</p>
</summary>
<category term="图论" scheme="http://hydingsy.github.io/tags/%E5%9B%BE%E8%AE%BA/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="邻接矩阵" scheme="http://hydingsy.github.io/tags/%E9%82%BB%E6%8E%A5%E7%9F%A9%E9%98%B5/"/>
<category term="Tarjan" scheme="http://hydingsy.github.io/tags/Tarjan/"/>
<category term="强连通分量" scheme="http://hydingsy.github.io/tags/%E5%BC%BA%E8%BF%9E%E9%80%9A%E5%88%86%E9%87%8F/"/>
</entry>
<entry>
<title>「Codeforces 1131D」Gourmet Choice</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-1131D-Gourmet-Choice/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-1131D-Gourmet-Choice/</id>
<published>2019-03-01T16:00:00.000Z</published>
<updated>2019-03-02T03:04:20.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/1131/problem/D" target="_blank" rel="noopener">Codeforces 1131D</a></p></blockquote><p>美食家 Apple 先生是一家美食杂志的主编。他会用一个正整数来评价每一道菜。</p><p>美食家在第一天品尝第 $n$ 道菜,第二天品尝了 $m$ 道菜。他制作了一张 $n\times m$ 的表格,记录了他对菜肴的评价。如果第一套中的第 $i$ 道菜比第二套中的第 $j$ 道菜好,那么 $a_{i,j}$ 等于 <code>></code>;如果要差,那么 $a_{i,j}$ 等于 <code><</code>。菜肴可能同样美味,那么 $a_{i,j}$ 等于 <code>=</code>。</p><p>现在 Apple 先生想让你帮他评价每道菜。由于他是非常严格的,他会对菜肴进行评估,以便使用的最大整数尽可能小。但是 Apple 先生也很公平,如果 $a_{i,j}$ 为 <code><</code>,那么给第一套中第 $i$ 道菜的评价一定小于第二套中第 $j$ 道菜。如果 $a_{i,j}$ 是 <code>></code> 那么应该要更大。如果 $a_{i,j}$ 为 <code>=</code>,那么这两个数字要相等。</p><p>帮助 Apple 先生评价这两套中的每一道菜,使之符合他的感受,并满足最大数字尽可能小。如果有解则输出 <code>Yes</code> 和评价的数字;否则输出 <code>No</code>。</p><p>数据范围:$1\le n,m\le 10^3$。</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>首先我们把 <code>=</code> 给处理掉,把所有相等的点缩在一起。如果同一个并查集中的点有 <code><</code> 或 <code>></code> 关系显然无解。</p><p>此时我们得到了一个有向图,直接对它<strong>拓扑排序</strong>,如果有环则无解,否则输出方案。</p><p><strong>时间复杂度</strong>:$O(nm)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><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">include</span> <span class="meta-string"><cstdlib></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"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> fail puts(<span class="meta-string">"No"</span>),exit(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">2e3</span>+<span class="number">5</span>,M=<span class="number">2e6</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> n,m,cnt,tot,lnk[N],ter[M],nxt[M],fa[N],bel[N],deg[N],dis[N];</span><br><span class="line"><span class="keyword">bool</span> vis[N];</span><br><span class="line"><span class="keyword">char</span> s[N][N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> v)</span> </span>{</span><br><span class="line"> ter[++tot]=v,nxt[tot]=lnk[u],lnk[u]=tot,++deg[v];</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">find</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> fa[x]==x?x:fa[x]=find(fa[x]);</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"> <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<=n+m;++i) fa[i]=i;</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 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<=m;++j) <span class="keyword">if</span>(s[i][j]==<span class="string">'='</span>) fa[find(i)]=find(n+j);</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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;++j) {</span><br><span class="line"> <span class="keyword">if</span>(s[i][j]!=<span class="string">'='</span>&&find(i)==find(n+j)) fail;</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+m;++i) <span class="keyword">if</span>(find(i)==i) bel[i]=++cnt;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n+m;++i) bel[i]=bel[find(i)];</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> </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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;++j) {</span><br><span class="line"> <span class="keyword">if</span>(s[i][j]==<span class="string">'<'</span>) add(bel[i],bel[j+n]);</span><br><span class="line"> <span class="keyword">if</span>(s[i][j]==<span class="string">'>'</span>) add(bel[j+n],bel[i]);</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">std</span>::<span class="built_in">queue</span><<span class="keyword">int</span>> q;</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 class="keyword">if</span>(!deg[i]) dis[i]=<span class="number">1</span>,q.push(i);</span><br><span class="line"> <span class="keyword">while</span>(!q.empty()) {</span><br><span class="line"> <span class="keyword">int</span> u=q.front(); q.pop();</span><br><span class="line"> vis[u]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> dis[v]=<span class="built_in">std</span>::max(dis[v],dis[u]+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">if</span>(!--deg[v]) q.push(v);</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<=cnt;++i) <span class="keyword">if</span>(!vis[i]) fail;</span><br><span class="line"> <span class="built_in">puts</span>(<span class="string">"Yes"</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n+m;++i) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d%c"</span>,dis[bel[i]],<span class="string">" \n"</span>[i==n||i==n+m]);</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"> init();</span><br><span class="line"> build();</span><br><span class="line"> solve();</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/1131/problem/D" target="_blank" rel="noopener">Codeforces 1131D</a></p>
</blockquote>
<p>美食家 Apple 先生是一家美食杂志的主编。他会用一个正整数来评价每一道菜。</p>
<p>美食家在第一天品尝第 $n$ 道菜,第二天品尝了 $m$ 道菜。他制作了一张 $n\times m$ 的表格,记录了他对菜肴的评价。如果第一套中的第 $i$ 道菜比第二套中的第 $j$ 道菜好,那么 $a_{i,j}$ 等于 <code>&gt;</code>;如果要差,那么 $a_{i,j}$ 等于 <code>&lt;</code>。菜肴可能同样美味,那么 $a_{i,j}$ 等于 <code>=</code>。</p>
<p>现在 Apple 先生想让你帮他评价每道菜。由于他是非常严格的,他会对菜肴进行评估,以便使用的最大整数尽可能小。但是 Apple 先生也很公平,如果 $a_{i,j}$ 为 <code>&lt;</code>,那么给第一套中第 $i$ 道菜的评价一定小于第二套中第 $j$ 道菜。如果 $a_{i,j}$ 是 <code>&gt;</code> 那么应该要更大。如果 $a_{i,j}$ 为 <code>=</code>,那么这两个数字要相等。</p>
<p>帮助 Apple 先生评价这两套中的每一道菜,使之符合他的感受,并满足最大数字尽可能小。如果有解则输出 <code>Yes</code> 和评价的数字;否则输出 <code>No</code>。</p>
<p>数据范围:$1\le n,m\le 10^3$。</p>
</summary>
<category term="图论" scheme="http://hydingsy.github.io/tags/%E5%9B%BE%E8%AE%BA/"/>
<category term="拓扑排序" scheme="http://hydingsy.github.io/tags/%E6%8B%93%E6%89%91%E6%8E%92%E5%BA%8F/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="缩点" scheme="http://hydingsy.github.io/tags/%E7%BC%A9%E7%82%B9/"/>
</entry>
<entry>
<title>「Codeforces 788E」New Task</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-788E-New-Task/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-788E-New-Task/</id>
<published>2019-02-27T16:00:00.000Z</published>
<updated>2019-02-28T23:59:44.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/788/problem/E" target="_blank" rel="noopener">Codeforces 788E</a></p></blockquote><p>在第 228 届国际 Uzhlyandian 战略比赛中,各队均由 $5$ 名队员组成。</p><p>Masha 是新的国防部长,这位部长的主要职责是计算军队的效率。军队由 $n$ 名士兵组成,标号为 $1$ 到 $n$,第 $i$ 个士兵的技能值为 $a_i$。</p><p>这个队伍将由 $3$ 名队员和 $2$ 名助手组成,队员的技能值是相同的,助手的技能值不大于队员的技能值。对于 Masha 而言,助手应该分别站在队员的最左侧和最右侧。形式化地说,一个队伍有 $5$ 名士兵,下标为 $i,j,k,l,p$ 满足 $1\le i<j<k<l<p\le n$ 并且 $a_i\le a_j=a_k=a_l\ge a_p$。</p><p>军队的效率是 Masha 可以选择的不同队伍的数量。两个队伍是不同的当且仅当有至少一个人不同。</p><p>最初,所有的士兵都可以成为队员。由于某些原因,有时一些士兵不能成为队员或可以成为队员;但是所有士兵在任何时候都可以成为助手。Masha 有 $m$ 次操作,每次可以令第 $x$ 个士兵可以成为队员或不能。她需要你求出每次操作后可以选择的队伍数量,答案对 $10^9+7$ 取模。</p><p>数据范围:$1\le n,m\le 10^5$,$1\le a_i\le 10^9$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>由于每个士兵都可以成为助手,我们设 $pre_i$ 和 $suf_i$ 分别表示 $i$ 左边和右边比 $a_i$ 小的数的个数。可以<strong>离散化</strong>后用树状数组求出。</p><p>由于有动态修改,并且区间看起来是可以合并的,我们考虑用线段树维护。</p><p>由于第 $1,5$ 个人无关紧要的,我们<strong>只关心中间的 $3$ 个人</strong>。又因为每个权值都是独立的,因此<strong>对每种权值建立一棵线段树</strong>(当然要采用动态开点)。</p><p>每个节点维护 $6$ 个值(其中 $p$ 为根节点,$[l,r]$ 为根节点维护的区间,$ls,rs$ 为左右儿子):</p><table class="table table-bordered table-text-center table-vertical-middle"><thead> <tr><th>变量</th><th>含义</th><th>单点初值</th><th>转移</th></tr></thead><tbody> <tr><td>$A$</td><td>选择第 $1$ 个人的方案数</td><td>$pre_l$</td><td>$A_p=A_{ls}+A_{rs}$</td></tr> <tr><td>$B$</td><td>选择第 $2$ 个人的方案数</td><td>$1$</td><td>$B_p=B_{ls}+B_{rs}$</td></tr> <tr><td>$C$</td><td>选择第 $3$ 个人的方案数</td><td>$suf_r$</td><td>$C_p=C_{ls}+C_{rs}$</td></tr> <tr><td>$AB$</td><td>选择第 $1,2$ 个人的方案数</td><td>$0$</td><td>$AB_p=AB_{ls}+AB_{rs}+A_{ls}\cdot B_{rs}$</td></tr> <tr><td>$BC$</td><td>选择第 $2,3$ 个人的方案数</td><td>$0$</td><td>$BC_p=BC_{ls}+BC_{rs}+B_{ls}\cdot C_{rs}$</td></tr> <tr><td>$ABC$</td><td>选择第 $1,2,3$ 个人的方案数</td><td>$0$</td><td>$ABC_p=ABC_{ls}+ABC_{rs}+AB_{ls}\cdot C_{rs}+A_{ls}\cdot BC_{rs}$</td></tr></tbody></table><p>具体实现见代码。</p><p><strong>时间复杂度</strong>:$O((n+m)\log n)$(注意空间复杂度和主席树类似)</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br></pre></td><td class="code"><pre><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">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"><algorithm></span></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">1e5</span>+<span class="number">5</span>,M=N*<span class="number">20</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod=<span class="number">1e9</span>+<span class="number">7</span>;</span><br><span class="line"><span class="keyword">int</span> n,m,tot,a[N],b[N],pre[N],suf[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">upd</span><span class="params">(<span class="keyword">int</span> &x,<span class="keyword">int</span> y)</span> </span>{</span><br><span class="line"> (x+=y)>=mod&&(x-=mod);</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Bit</span> {</span></span><br><span class="line"> <span class="keyword">int</span> b[N];</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="built_in">memset</span>(b,<span class="number">0</span>,<span class="keyword">sizeof</span>(b));</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">modify</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> v)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span>(;x<=n;x+=x&-x) b[x]+=v;</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">query</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(;x;x^=x&-x) ans+=b[x];</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">} bit;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Segment</span> {</span></span><br><span class="line"> <span class="keyword">int</span> rt[N],ls[M],rs[M],A[M],B[M],C[M],AB[M],BC[M],ABC[M];</span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">plus</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">int</span> c=x+y;</span><br><span class="line"> <span class="keyword">return</span> c>=mod?c-mod:c;</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">int</span> <span class="title">mul</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> <span class="number">1L</span>L*x*y%mod;</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">pushup</span><span class="params">(<span class="keyword">int</span> p)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> l=ls[p],r=rs[p];</span><br><span class="line"> A[p]=plus(A[l],A[r]);</span><br><span class="line"> B[p]=plus(B[l],B[r]);</span><br><span class="line"> C[p]=plus(C[l],C[r]);</span><br><span class="line"> AB[p]=plus(plus(AB[l],AB[r]),mul(A[l],B[r]));</span><br><span class="line"> BC[p]=plus(plus(BC[l],BC[r]),mul(B[l],C[r]));</span><br><span class="line"> ABC[p]=plus(plus(ABC[l],ABC[r]),plus(mul(A[l],BC[r]),mul(AB[l],C[r])));</span><br><span class="line"> }</span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">modify</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> &p,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> v)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(!p) p=++tot;</span><br><span class="line"> <span class="keyword">if</span>(l==r) {</span><br><span class="line"> A[p]=v*pre[x];</span><br><span class="line"> B[p]=v;</span><br><span class="line"> C[p]=v*suf[x];</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> mid=(l+r)>><span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(x<=mid) modify(x,ls[p],l,mid,v);</span><br><span class="line"> <span class="keyword">else</span> modify(x,rs[p],mid+<span class="number">1</span>,r,v);</span><br><span class="line"> pushup(p);</span><br><span class="line"> }</span><br><span class="line">} seg;</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"> <span class="built_in">std</span>::sort(b+<span class="number">1</span>,b+n+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">int</span> sz=<span class="built_in">std</span>::unique(b+<span class="number">1</span>,b+n+<span class="number">1</span>)-(b+<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) a[i]=<span class="built_in">std</span>::lower_bound(b+<span class="number">1</span>,b+sz+<span class="number">1</span>,a[i])-b;</span><br><span class="line"> bit.init();</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;++i) pre[i]=bit.query(a[i]),bit.modify(a[i],<span class="number">1</span>);</span><br><span class="line"> bit.init();</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n;i>=<span class="number">1</span>;--i) suf[i]=bit.query(a[i]),bit.modify(a[i],<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">main</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 class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;++i) <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&a[i]),b[i]=a[i];</span><br><span class="line"> init();</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;++i) seg.modify(i,seg.rt[a[i]],<span class="number">1</span>,n,<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">int</span> ans=<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) upd(ans,seg.ABC[seg.rt[i]]);</span><br><span class="line"> <span class="keyword">for</span>(<span class="built_in">scanf</span>(<span class="string">"%d"</span>,&m);m--;) {</span><br><span class="line"> <span class="keyword">int</span> opt,x;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&opt,&x);</span><br><span class="line"> <span class="keyword">int</span> &rt=seg.rt[a[x]];</span><br><span class="line"> upd(ans,mod-seg.ABC[rt]);</span><br><span class="line"> seg.modify(x,rt,<span class="number">1</span>,n,opt<span class="number">-1</span>);</span><br><span class="line"> upd(ans,seg.ABC[rt]);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\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>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/788/problem/E" target="_blank" rel="noopener">Codeforces 788E</a></p>
</blockquote>
<p>在第 228 届国际 Uzhlyandian 战略比赛中,各队均由 $5$ 名队员组成。</p>
<p>Masha 是新的国防部长,这位部长的主要职责是计算军队的效率。军队由 $n$ 名士兵组成,标号为 $1$ 到 $n$,第 $i$ 个士兵的技能值为 $a_i$。</p>
<p>这个队伍将由 $3$ 名队员和 $2$ 名助手组成,队员的技能值是相同的,助手的技能值不大于队员的技能值。对于 Masha 而言,助手应该分别站在队员的最左侧和最右侧。形式化地说,一个队伍有 $5$ 名士兵,下标为 $i,j,k,l,p$ 满足 $1\le i&lt;j&lt;k&lt;l&lt;p\le n$ 并且 $a_i\le a_j=a_k=a_l\ge a_p$。</p>
<p>军队的效率是 Masha 可以选择的不同队伍的数量。两个队伍是不同的当且仅当有至少一个人不同。</p>
<p>最初,所有的士兵都可以成为队员。由于某些原因,有时一些士兵不能成为队员或可以成为队员;但是所有士兵在任何时候都可以成为助手。Masha 有 $m$ 次操作,每次可以令第 $x$ 个士兵可以成为队员或不能。她需要你求出每次操作后可以选择的队伍数量,答案对 $10^9+7$ 取模。</p>
<p>数据范围:$1\le n,m\le 10^5$,$1\le a_i\le 10^9$</p>
</summary>
<category term="数据结构" scheme="http://hydingsy.github.io/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
<category term="线段树" scheme="http://hydingsy.github.io/tags/%E7%BA%BF%E6%AE%B5%E6%A0%91/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="树状数组" scheme="http://hydingsy.github.io/tags/%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84/"/>
<category term="计数" scheme="http://hydingsy.github.io/tags/%E8%AE%A1%E6%95%B0/"/>
</entry>
<entry>
<title>「UOJ 454」打雪仗</title>
<link href="http://hydingsy.github.io/articles/problem-UOJ-454-Snowball-Fight/"/>
<id>http://hydingsy.github.io/articles/problem-UOJ-454-Snowball-Fight/</id>
<published>2019-02-26T16:00:00.000Z</published>
<updated>2019-03-02T03:54:12.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="http://uoj.ac/problem/454" target="_blank" rel="noopener">UOJ 454</a></p></blockquote><p>这是一道通信题。</p><p>小 A 有一个长度为 $2n$ 的 $01$ 字符串 $S$,小 B 有 $\{1,\dots,2n\}$ 这些下标中的 $n$ 个:$p_1,\dots,p_n$。小 A 和小 B 可以相互之间可以发送字符(但只能发送 <code>0</code> 或者 <code>1</code> 两种)。请为小 A 和小 B 设计一种通信方式,使得小 B 最终能知道这 $n$ 个下标所对应的字符 $S[p_1],S[p_2],\dots,S[p_n]$。两人中发送字符数较多的那一个不应发送超过 $m$ 个字符。</p><p>数据范围:$n=1000$,$m=1350$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>我们把这 $2n$ 个下标分为 $k$ 块,定义第 $i$ 个块中小 B 需要的下标有 $s_i$ 个。由于小 B 知道的 $n$ 个下标是总数的一半,那么至少有一个块中 $s_i$ 不小于块的长度的一半。我们考虑这样一个策略:</p><ul><li><p>把这 $k$ 个块中的其中 $c$ 个块让小 A 暴力发送给小 B。其余块中的下标让小 B 告诉小 A 是否要发送。</p></li><li><p>为了最大化暴力发送的效率,我们要选择 $s_i$ 最大的那 $c$ 个块。考虑最坏情况:$s_i$ 均为块长度的一半。</p></li><li><p>通过简单计算我们可以得到:</p><p>小 A 的发送次数:$n+\frac{c}{k}\cdot n$</p><p>小 B 的发送次数:$2n-\frac{c}{k}\cdot 2n$</p></li><li><p>计算不等式得到:$0.325\le \frac{c}{k}\le 0.35$。</p></li><li><p>这样一来我们取 $\frac{c}{k}=\frac{1}{3}=0.333\dots$ 就行了。</p></li></ul><p><strong>时间复杂度</strong>:$O(n)$</p><p><strong>发送字符数</strong>:不超过 $\frac{4}{3}n$ 个字符。</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><h3 id="Alice"><a href="#Alice" class="headerlink" title="Alice"></a>Alice</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></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><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N=<span class="number">2e3</span>+<span class="number">5</span>;</span><br><span class="line">FILE *in=fopen(<span class="string">"alice.in"</span>,<span class="string">"r"</span>);</span><br><span class="line"><span class="keyword">int</span> n;</span><br><span class="line"><span class="keyword">char</span> s[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">send</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="built_in">putchar</span>(x+<span class="string">'0'</span>),fflush(<span class="built_in">stdout</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">get</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> getchar()^<span class="number">48</span>;</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 class="keyword">int</span> l,<span class="keyword">int</span> r)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=l;i<=r;++i) send(s[i]-<span class="string">'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 class="keyword">if</span>(i<l||i>r) {</span><br><span class="line"> <span class="keyword">if</span>(get()) send(s[i]-<span class="string">'0'</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">fscanf</span>(in,<span class="string">"%d%*d%s"</span>,&n,s+<span class="number">1</span>),n<<=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> l1=<span class="number">1</span>,r1=n/<span class="number">3</span>,l2=r1+<span class="number">1</span>,r2=n/<span class="number">3</span>*<span class="number">2</span>,l3=r2+<span class="number">1</span>,r3=n;</span><br><span class="line"> <span class="keyword">int</span> opt=<span class="number">2</span>*get()+get();</span><br><span class="line"> <span class="keyword">if</span>(opt==<span class="number">1</span>) solve(l1,r1);</span><br><span class="line"> <span class="keyword">if</span>(opt==<span class="number">2</span>) solve(l2,r2);</span><br><span class="line"> <span class="keyword">if</span>(opt==<span class="number">3</span>) solve(l3,r3);</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><h3 id="Bob"><a href="#Bob" class="headerlink" title="Bob"></a>Bob</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><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">include</span> <span class="meta-string"><algorithm></span></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">2e3</span>+<span class="number">5</span>;</span><br><span class="line">FILE *in=fopen(<span class="string">"bob.in"</span>,<span class="string">"r"</span>),*out=fopen(<span class="string">"bob.out"</span>,<span class="string">"w"</span>);</span><br><span class="line"><span class="keyword">int</span> n,p[N],vis[N],ans[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">send</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="built_in">putchar</span>(x+<span class="string">'0'</span>),fflush(<span class="built_in">stdout</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">get</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> getchar()^<span class="number">48</span>;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">calc</span><span class="params">(<span class="keyword">int</span> l,<span class="keyword">int</span> r)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=l;i<=r;++i) ans+=vis[i];</span><br><span class="line"> <span class="keyword">return</span> ans;</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 class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> o1,<span class="keyword">int</span> o2)</span> </span>{</span><br><span class="line"> send(o1),send(o2);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=l;i<=r;++i) ans[i]=get();</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 class="keyword">if</span>(i<l||i>r) {</span><br><span class="line"> send(vis[i]);</span><br><span class="line"> <span class="keyword">if</span>(vis[i]) ans[i]=get();</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">fscanf</span>(in,<span class="string">"%d%*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">fscanf</span>(in,<span class="string">"%d"</span>,&p[i]);</span><br><span class="line"> vis[p[i]]=<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> n<<=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">int</span> l1=<span class="number">1</span>,r1=n/<span class="number">3</span>,l2=r1+<span class="number">1</span>,r2=n/<span class="number">3</span>*<span class="number">2</span>,l3=r2+<span class="number">1</span>,r3=n;</span><br><span class="line"> <span class="keyword">int</span> c1=calc(l1,r1),c2=calc(l2,r2),c3=calc(l3,r3);</span><br><span class="line"> <span class="keyword">int</span> mx=<span class="built_in">std</span>::max(c1,<span class="built_in">std</span>::max(c2,c3));</span><br><span class="line"> mx==c1?solve(l1,r1,<span class="number">0</span>,<span class="number">1</span>):mx==c2?solve(l2,r2,<span class="number">1</span>,<span class="number">0</span>):solve(l3,r3,<span class="number">1</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<=n;++i) <span class="keyword">if</span>(vis[i]) <span class="built_in">fprintf</span>(out,<span class="string">"%d"</span>,ans[i]);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="http://uoj.ac/problem/454" target="_blank" rel="noopener">UOJ 454</a></p>
</blockquote>
<p>这是一道通信题。</p>
<p>小 A 有一个长度为 $2n$ 的 $01$ 字符串 $S$,小 B 有 $\{1,\dots,2n\}$ 这些下标中的 $n$ 个:$p_1,\dots,p_n$。小 A 和小 B 可以相互之间可以发送字符(但只能发送 <code>0</code> 或者 <code>1</code> 两种)。请为小 A 和小 B 设计一种通信方式,使得小 B 最终能知道这 $n$ 个下标所对应的字符 $S[p_1],S[p_2],\dots,S[p_n]$。两人中发送字符数较多的那一个不应发送超过 $m$ 个字符。</p>
<p>数据范围:$n=1000$,$m=1350$</p>
</summary>
<category term="UOJ" scheme="http://hydingsy.github.io/tags/UOJ/"/>
<category term="贪心" scheme="http://hydingsy.github.io/tags/%E8%B4%AA%E5%BF%83/"/>
<category term="构造" scheme="http://hydingsy.github.io/tags/%E6%9E%84%E9%80%A0/"/>
<category term="通信题" scheme="http://hydingsy.github.io/tags/%E9%80%9A%E4%BF%A1%E9%A2%98/"/>
</entry>
<entry>
<title>「APIO 2016」Gap</title>
<link href="http://hydingsy.github.io/articles/problem-APIO-2016-Gap/"/>
<id>http://hydingsy.github.io/articles/problem-APIO-2016-Gap/</id>
<published>2019-02-26T16:00:00.000Z</published>
<updated>2019-02-28T03:06:46.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="">UOJ 206</a></p></blockquote><p>这是一道交互题。</p><p>有 $n$ 个严格递增的非负整数 $a_1,a_2,\dots,a_n$($0\le a_1<a_2<\dots<a_n\le 10^{18}$)。你需要找出 $a_{i+1}−a_i$($1\le i\le n-1$)里的最大的值。</p><p>你的程序不能直接读入这个整数序列,但是你可以通过给定的函数来查询该序列的信息。关于查询函数的细节,请根据你所使用的语言,参考下面的实现细节部分。</p><p>你需要实现一个函数,该函数返回 $a_{i+1}−a_i$($1\le i\le n-1$)中的最大值。</p><h3 id="实现细节(C-C-)"><a href="#实现细节(C-C-)" class="headerlink" title="实现细节(C/C++)"></a>实现细节(C/C++)</h3><p>你需要包含头文件 <code>gap.h</code>。</p><p>你需要实现一个函数 $\text{findGap}(T,N)$,该函数接受下面的参数,并返回一个 $\text{long long}$ 类型的整数:</p><ul><li>$T$:子任务的编号($1$ 或者 $2$)</li><li>$N$:序列的长度</li></ul><p>你的函数 $\text{findGap}$ 可以调用系统提供的查询函数 $\text{MinMax}(s,t,\&mn,\&mx)$,该函数的前两个参数 $s$ 和 $t$ 是 $\text{long long}$ 类型的整数,后两个参数 $\&mn$ 和 $\&mx$ 是 $\text{long long}$ 类型的整数的指针($mn$ 和 $mx$ 是 $\text{long long}$ 类型的整数)。当 $\text{MinMax}(s,t,\&mn,\&mx)$ 返回时,变量 $mn$ 将会存储满足 $a_i\in [s,t]$ 中 $a_i$ 的最小值,变量 $mx$ 将会存储满足 $a_i\in[s,t]$ 中 $a_i$ 的最大值。如果区间 $[s,t]$ 中没有序列中的数,则 $mn$ 和 $mx$ 都将存储 $-1$。在查询时需要满足 $s\le t$,否则程序将会终止,该测试点计为 $0$ 分。</p><h3 id="限制与约定"><a href="#限制与约定" class="headerlink" title="限制与约定"></a>限制与约定</h3><p>对于所有的测试点,有 $2\le n\le 10^5$。</p><p>每一个测试点开始测试之前,$M$ 都将被初始化为 $0$。</p><p>子任务 $1$($30$ 分):每一次调用 $\text{MinMax}$ 都将使 $M$ 加 $1$。为了获得所有分数,需要满足对于该子任务下的所有测试点,都有 $M\le \frac{n+1}{2}$。</p><p>子任务 $2$($70$ 分):定义 $k$ 为调用 $\text{MinMax}$ 时,区间 $[s,t]$ 中的序列中数的数量。每次调用 $\text{MinMax}$,将使 $M$ 加上 $k+1$。对于每一个测试点,如果 $M\le 3n$,你将得到 $70$ 分,否则将得到 $\frac{60}{\sqrt{\frac{M}{n}+1}-1}$ 分。你的该子任务的得分是其下所有测试点中的最低分。</p><h3 id="下载"><a href="#下载" class="headerlink" title="下载"></a>下载</h3><p><a href="http://uoj.ac/download.php?type=problem&id=206" target="_blank" rel="noopener">样例及测评库下载</a></p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><h3 id="子任务-1"><a href="#子任务-1" class="headerlink" title="子任务 1"></a>子任务 1</h3><p>由于有 $0\le a_1<a_2<\dots<a_n\le 10^{18}$ 这个限制,我们可以<strong>从两头向中间</strong>询问,第一次询问 $[0,10^{18}]$ 得到 $a_1,a_n$ 的值,接下来询问 $[a_1+1,a_n-1]$ 得到 $a_2,a_{n-1}$ 的值……以此类推,我们可以发现询问次数恰好是 $\frac{n+1}{2}$,可以通过本子任务。</p><h3 id="子任务-2"><a href="#子任务-2" class="headerlink" title="子任务 2"></a>子任务 2</h3><p>我们先确定<strong>答案的下界</strong>:设 $s,t$ 为询问 $[0,10^{18}]$ 得到的结果,那么通过<strong>鸽巢原理</strong>可以得到答案的下界为 $\left\lfloor\frac{t-s}{n-1}\right\rfloor$,记为 $p$(两个数之间的最大间隔最少为 $p$)。这样一来,我们就<strong>只关心那些长度为 $p+1$ 的区间</strong>了。</p><p>设当前询问的区间为 $[l,r]$(初始值 $l=s+1$,且显然有 $r=l+p$),得到的结果为 $mn,mx$(当 $mn=-1,mx=-1$ 时忽略这个区间);那么我们用 $mn-\text{上一个出现的数字}$ 来更新答案,并将 $\text{上一个出现的数字}$ 设为 $mx$。接下来询问区间 $[l’,r’]$(其中 $l’=r+1,r’=l’+p$),不断更新答案直到 $l>t$ 为止。</p><p>最后证明一下 $M\le 3n$。第一次询问得到 $[s,t]$ 后 $k=n$,接下来不超过 $n-1$ 次询问,总共包含不超过 $n$ 个点,故 $M\le (n+1)+(n-1)+n\le 3n$,符合条件。</p><p> <strong>时间复杂度</strong>:$O(n)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><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">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">"gap.h"</span></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">1e5</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">long</span> a[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">findGap</span><span class="params">(<span class="keyword">int</span> T,<span class="keyword">int</span> n)</span> </span>{</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span>(T==<span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> s=<span class="number">0</span>,t=<span class="number">1e18</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> l=<span class="number">1</span>,r=n;l<=r;++l,--r) MinMax(s,t,&a[l],&a[r]),s=a[l]+<span class="number">1</span>,t=a[r]<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<=n;++i) ans=<span class="built_in">std</span>::max(ans,a[i]-a[i<span class="number">-1</span>]);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> s,t;</span><br><span class="line"> MinMax(<span class="number">0</span>,<span class="number">1e18</span>,&s,&t);</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> p=(t-s)/(n<span class="number">-1</span>),pre=s;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">long</span> <span class="keyword">long</span> i=s+<span class="number">1</span>;i<=t;i+=p+<span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> mn,mx;</span><br><span class="line"> MinMax(i,i+p,&mn,&mx);</span><br><span class="line"> <span class="keyword">if</span>(~mn) ans=<span class="built_in">std</span>::max(ans,mn-pre),pre=mx;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="">UOJ 206</a></p>
</blockquote>
<p>这是一道交互题。</p>
<p>有 $n$ 个严格递增的非负整数 $a_1,a_2,\dots,a_n$($0\le a_1&lt;a_2&lt;\dots&lt;a_n\le 10^{18}$)。你需要找出 $a_{i+1}−a_i$($1\le i\le n-1$)里的最大的值。</p>
<p>你的程序不能直接读入这个整数序列,但是你可以通过给定的函数来查询该序列的信息。关于查询函数的细节,请根据你所使用的语言,参考下面的实现细节部分。</p>
<p>你需要实现一个函数,该函数返回 $a_{i+1}−a_i$($1\le i\le n-1$)中的最大值。</p>
<h3 id="实现细节(C-C-)"><a href="#实现细节(C-C-)" class="headerlink" title="实现细节(C/C++)"></a>实现细节(C/C++)</h3><p>你需要包含头文件 <code>gap.h</code>。</p>
<p>你需要实现一个函数 $\text{findGap}(T,N)$,该函数接受下面的参数,并返回一个 $\text{long long}$ 类型的整数:</p>
<ul>
<li>$T$:子任务的编号($1$ 或者 $2$)</li>
<li>$N$:序列的长度</li>
</ul>
<p>你的函数 $\text{findGap}$ 可以调用系统提供的查询函数 $\text{MinMax}(s,t,\&amp;mn,\&amp;mx)$,该函数的前两个参数 $s$ 和 $t$ 是 $\text{long long}$ 类型的整数,后两个参数 $\&amp;mn$ 和 $\&amp;mx$ 是 $\text{long long}$ 类型的整数的指针($mn$ 和 $mx$ 是 $\text{long long}$ 类型的整数)。当 $\text{MinMax}(s,t,\&amp;mn,\&amp;mx)$ 返回时,变量 $mn$ 将会存储满足 $a_i\in [s,t]$ 中 $a_i$ 的最小值,变量 $mx$ 将会存储满足 $a_i\in[s,t]$ 中 $a_i$ 的最大值。如果区间 $[s,t]$ 中没有序列中的数,则 $mn$ 和 $mx$ 都将存储 $-1$。在查询时需要满足 $s\le t$,否则程序将会终止,该测试点计为 $0$ 分。</p>
<h3 id="限制与约定"><a href="#限制与约定" class="headerlink" title="限制与约定"></a>限制与约定</h3><p>对于所有的测试点,有 $2\le n\le 10^5$。</p>
<p>每一个测试点开始测试之前,$M$ 都将被初始化为 $0$。</p>
<p>子任务 $1$($30$ 分):每一次调用 $\text{MinMax}$ 都将使 $M$ 加 $1$。为了获得所有分数,需要满足对于该子任务下的所有测试点,都有 $M\le \frac{n+1}{2}$。</p>
<p>子任务 $2$($70$ 分):定义 $k$ 为调用 $\text{MinMax}$ 时,区间 $[s,t]$ 中的序列中数的数量。每次调用 $\text{MinMax}$,将使 $M$ 加上 $k+1$。对于每一个测试点,如果 $M\le 3n$,你将得到 $70$ 分,否则将得到 $\frac{60}{\sqrt{\frac{M}{n}+1}-1}$ 分。你的该子任务的得分是其下所有测试点中的最低分。</p>
<h3 id="下载"><a href="#下载" class="headerlink" title="下载"></a>下载</h3><p><a href="http://uoj.ac/download.php?type=problem&amp;id=206" target="_blank" rel="noopener">样例及测评库下载</a></p>
</summary>
<category term="APIO" scheme="http://hydingsy.github.io/tags/APIO/"/>
<category term="UOJ" scheme="http://hydingsy.github.io/tags/UOJ/"/>
<category term="交互题" scheme="http://hydingsy.github.io/tags/%E4%BA%A4%E4%BA%92%E9%A2%98/"/>
<category term="鸽巢原理" scheme="http://hydingsy.github.io/tags/%E9%B8%BD%E5%B7%A2%E5%8E%9F%E7%90%86/"/>
</entry>
<entry>
<title>「WC 2015」未来程序</title>
<link href="http://hydingsy.github.io/articles/problem-WC-2015-Future-Program/"/>
<id>http://hydingsy.github.io/articles/problem-WC-2015-Future-Program/</id>
<published>2019-02-25T16:00:00.000Z</published>
<updated>2019-03-03T02:42:42.139Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="http://uoj.ac/problem/73" target="_blank" rel="noopener">UOJ 73</a></p></blockquote><p>本题是一道提交答案题,一共有 $10$ 个测试点。</p><p>对于每个测试点,你会得到一段程序的源代码和这段程序的输入。你要运行这个程序,并保存这个程序的输出。</p><p>遗憾的是这些程序效率都极其低下,无法在比赛的 $5$ 小时内得到输出。</p><p>你需要帮助 B 君得到这些程序的输出。</p><p><a href="http://uoj.ac/download.php?type=problem&id=73" target="_blank" rel="noopener">输入数据下载</a></p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><h3 id="Program-1"><a href="#Program-1" class="headerlink" title="Program 1"></a>Program 1</h3><h4 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h4><p>给 $d$ 加上 $b$ 个 $a$,答案对 $c$ 取模(注意模数很大)。</p><h4 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h4><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><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><br><span class="line"><span class="keyword">long</span> <span class="keyword">long</span> a,b,mod;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">mul</span><span class="params">(<span class="keyword">long</span> <span class="keyword">long</span> x,<span class="keyword">long</span> <span class="keyword">long</span> p)</span> </span>{</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(;p;p>>=<span class="number">1</span>,x=(x+x)%mod) <span class="keyword">if</span>(p&<span class="number">1</span>) ans=(ans+x)%mod;</span><br><span class="line"> <span class="keyword">return</span> ans;</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"> freopen(<span class="string">"program1.in"</span>,<span class="string">"r"</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> freopen(<span class="string">"program1.out"</span>,<span class="string">"w"</span>,<span class="built_in">stdout</span>);</span><br><span class="line"> <span class="keyword">while</span>(~<span class="built_in">scanf</span>(<span class="string">"%lld%lld%lld"</span>,&a,&b,&mod)) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,mul(a,b,mod));</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="答案"><a href="#答案" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">11239440904485</span></span><br><span class="line"><span class="number">7551029211890</span></span><br><span class="line"><span class="number">20677492996370</span></span><br><span class="line"><span class="number">592966462292420</span></span><br><span class="line"><span class="number">69231182718627</span></span><br><span class="line"><span class="number">479525534330380</span></span><br><span class="line"><span class="number">544015996901435</span></span><br><span class="line"><span class="number">214227311823605</span></span><br><span class="line"><span class="number">73749675429767</span></span><br><span class="line"><span class="number">239498441843796</span></span><br></pre></td></tr></table></figure><h3 id="Program-2"><a href="#Program-2" class="headerlink" title="Program 2"></a>Program 2</h3><h4 id="分析-1"><a href="#分析-1" class="headerlink" title="分析"></a>分析</h4><p>可以找出 $a,b,c$ 的递推式子:</p><script type="math/tex; mode=display">a\leftarrow 1a+2b+1c\\b\leftarrow 1a+1b+0c\\c\leftarrow 1a+0b+0c\\</script><p>得到转移矩阵:</p><script type="math/tex; mode=display">\begin{bmatrix}1 & 2 & 1 \\1 & 1 & 0 \\1 & 0 & 0\end{bmatrix}</script><p>直接矩阵快速幂即可解决本题。</p><h4 id="代码-1"><a href="#代码-1" class="headerlink" title="代码"></a>代码</h4><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></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"><algorithm></span></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">4</span>;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">long</span> n,mod;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">upd</span><span class="params">(<span class="keyword">long</span> <span class="keyword">long</span> &x,<span class="keyword">long</span> <span class="keyword">long</span> y)</span> </span>{</span><br><span class="line"> (x+=y)>=mod&&(x-=mod);</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Matrix</span> {</span></span><br><span class="line"> <span class="keyword">int</span> n;</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> A[N][N];</span><br><span class="line"> Matrix(<span class="keyword">int</span> _n=<span class="number">0</span>) {</span><br><span class="line"> n=_n,<span class="built_in">memset</span>(A,<span class="number">0</span>,<span class="keyword">sizeof</span>(A));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">void</span> <span class="keyword">operator</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) A[i][i]=<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> Matrix <span class="keyword">operator</span> * (<span class="keyword">const</span> Matrix &b)<span class="keyword">const</span> {</span><br><span class="line"> <span class="function">Matrix <span class="title">ans</span><span class="params">(n)</span></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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) <span class="keyword">for</span>(<span class="keyword">int</span> k=<span class="number">1</span>;k<=n;++k) {</span><br><span class="line"> upd(ans.A[i][j],A[i][k]*b.A[k][j]%mod);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line"> Matrix <span class="keyword">operator</span> ^ (<span class="keyword">const</span> <span class="keyword">long</span> <span class="keyword">long</span> &b)<span class="keyword">const</span> {</span><br><span class="line"> Matrix ans(n),x=*this; ~ans;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">long</span> <span class="keyword">long</span> p=b;p;p>>=<span class="number">1</span>,x=x*x) <span class="keyword">if</span>(p&<span class="number">1</span>) ans=ans*x;</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> freopen(<span class="string">"program2.in"</span>,<span class="string">"r"</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> freopen(<span class="string">"program2.out"</span>,<span class="string">"w"</span>,<span class="built_in">stdout</span>);</span><br><span class="line"> <span class="keyword">while</span>(~<span class="built_in">scanf</span>(<span class="string">"%lld%lld"</span>,&n,&mod)) {</span><br><span class="line"> <span class="function">Matrix <span class="title">a</span><span class="params">(<span class="number">3</span>)</span></span>;</span><br><span class="line"> a.A[<span class="number">1</span>][<span class="number">1</span>]=<span class="number">1</span>,a.A[<span class="number">1</span>][<span class="number">2</span>]=<span class="number">2</span>,a.A[<span class="number">1</span>][<span class="number">3</span>]=<span class="number">1</span>;</span><br><span class="line"> a.A[<span class="number">2</span>][<span class="number">1</span>]=<span class="number">1</span>,a.A[<span class="number">2</span>][<span class="number">2</span>]=<span class="number">1</span>,a.A[<span class="number">3</span>][<span class="number">1</span>]=<span class="number">1</span>;</span><br><span class="line"> Matrix ans=a^n;</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> A=ans.A[<span class="number">1</span>][<span class="number">1</span>],B=ans.A[<span class="number">2</span>][<span class="number">1</span>],C=ans.A[<span class="number">3</span>][<span class="number">1</span>];</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,(A+mod-B+mod-B+C)%mod);</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><h4 id="答案-1"><a href="#答案-1" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">0</span></span><br><span class="line"><span class="number">1</span></span><br><span class="line"><span class="number">96</span></span><br><span class="line"><span class="number">64</span></span><br><span class="line"><span class="number">2503</span></span><br><span class="line"><span class="number">2523</span></span><br><span class="line"><span class="number">4452160</span></span><br><span class="line"><span class="number">557586868</span></span><br><span class="line"><span class="number">959316082</span></span><br><span class="line"><span class="number">1107500137</span></span><br></pre></td></tr></table></figure><h3 id="Program-3"><a href="#Program-3" class="headerlink" title="Program 3"></a>Program 3</h3><h4 id="分析-2"><a href="#分析-2" class="headerlink" title="分析"></a>分析</h4><p>容易发现:</p><script type="math/tex; mode=display">s_k=\sum_{i=0}^n i^k</script><p>其中任意数字的 $0$ 次方都定义为 $1$。</p><p>直接套用 $1,2,3,4$ 次方和公式即可。</p><script type="math/tex; mode=display">\begin{aligned}&s_0=n+1 \\&s_1=\frac{n(n+1)}{2} \\&s_2=\frac{n(n+1)(2n+1)}{6} \\&s_3=\frac{n^2(n+1)^2}{4} \\&s_4=\frac{n(n+1)(2n+1)(3n^2+3n-1)}{30}\end{aligned}</script><h4 id="代码-2"><a href="#代码-2" class="headerlink" title="代码"></a>代码</h4><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><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><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"> freopen(<span class="string">"program3.in"</span>,<span class="string">"r"</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> freopen(<span class="string">"program3.out"</span>,<span class="string">"w"</span>,<span class="built_in">stdout</span>);</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> n;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%llu"</span>,&n);</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> s0=n+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> s1=(n/<span class="number">2</span>)*(n+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> s2=(n/<span class="number">2</span>)*(n+<span class="number">1</span>)*((<span class="number">2</span>*n+<span class="number">1</span>)/<span class="number">3</span>);</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> s3=(n/<span class="number">2</span>)*(n/<span class="number">2</span>)*(n+<span class="number">1</span>)*(n+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> s4=(n/<span class="number">10</span>)*(n+<span class="number">1</span>)*((<span class="number">2</span>*n+<span class="number">1</span>)/<span class="number">3</span>)*(<span class="number">3</span>*n*n+<span class="number">3</span>*n<span class="number">-1</span>);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%llu\n%llu\n%llu\n%llu\n%llu\n%llu\n%llu\n%llu\n%llu\n%llu\n"</span>,s0,s0,s1,s1,s2,s2,s3,s3,s4,s4);</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><h4 id="答案-2"><a href="#答案-2" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1000000000000001</span></span><br><span class="line"><span class="number">1000000000000001</span></span><br><span class="line"><span class="number">2538972135152631808</span></span><br><span class="line"><span class="number">2538972135152631808</span></span><br><span class="line"><span class="number">2806098670314569728</span></span><br><span class="line"><span class="number">2806098670314569728</span></span><br><span class="line"><span class="number">6570342264898322432</span></span><br><span class="line"><span class="number">6570342264898322432</span></span><br><span class="line"><span class="number">10067259324320137216</span></span><br><span class="line"><span class="number">10067259324320137216</span></span><br></pre></td></tr></table></figure><h3 id="Program-4"><a href="#Program-4" class="headerlink" title="Program 4"></a>Program 4</h3><h4 id="分析-3"><a href="#分析-3" class="headerlink" title="分析"></a>分析</h4><p>对于 $\text{count1}$ 函数,就是求有多少个无序点对满足两个点都是 $1$。直接统计 $1$ 点个数即可。</p><p>对于 $\text{count2}$ 函数,就是对于每个 $1$ 点,求出到它曼哈顿距离最近的白点的距离。可以直接从 $0$ 点 $\text{BFS}$。</p><h4 id="代码-3"><a href="#代码-3" class="headerlink" title="代码"></a>代码</h4><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><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">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"><algorithm></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><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N=<span class="number">5e3</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dx[]={<span class="number">1</span>,<span class="number">-1</span>,<span class="number">0</span>,<span class="number">0</span>},dy[]={<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">-1</span>};</span><br><span class="line"><span class="keyword">int</span> n,m,type,seed,dis[N][N];</span><br><span class="line"><span class="keyword">bool</span> a[N][N],vis[N][N];</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> x,y,w;</span><br><span class="line"> Node(<span class="keyword">int</span> _x=<span class="number">0</span>,<span class="keyword">int</span> _y=<span class="number">0</span>,<span class="keyword">int</span> _w=<span class="number">0</span>) {</span><br><span class="line"> x=_x,y=_y,w=_w;</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">next_rand</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">int</span> P=<span class="number">1000000007</span>,Q=<span class="number">83978833</span>,R=<span class="number">8523467</span>;</span><br><span class="line"> <span class="keyword">return</span> seed=((<span class="keyword">long</span> <span class="keyword">long</span>)Q*seed%P*seed+R)%P;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">generate_input</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>,&n,&m,&type);</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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;++j) a[i][j]=(next_rand()%<span class="number">8</span>><span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">count1</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> ans=<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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;++j) ans+=a[i][j];</span><br><span class="line"> <span class="keyword">return</span> ans*(ans<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">count2</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">queue</span><Node> q;</span><br><span class="line"> <span class="built_in">memset</span>(dis,<span class="number">0x3f</span>,<span class="keyword">sizeof</span>(dis));</span><br><span class="line"> <span class="built_in">memset</span>(vis,<span class="number">1</span>,<span class="keyword">sizeof</span>(vis));</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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;++j) {</span><br><span class="line"> <span class="keyword">if</span>(!a[i][j]) dis[i][j]=<span class="number">0</span>,vis[i][j]=<span class="number">1</span>,q.push(Node(i,j,<span class="number">0</span>));</span><br><span class="line"> <span class="keyword">else</span> vis[i][j]=<span class="number">0</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span>(!q.empty()) {</span><br><span class="line"> Node u=q.front(); q.pop();</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">4</span>;++i) {</span><br><span class="line"> <span class="keyword">int</span> x=u.x+dx[i],y=u.y+dy[i];</span><br><span class="line"> <span class="keyword">if</span>(vis[x][y]) <span class="keyword">continue</span>;</span><br><span class="line"> vis[x][y]=<span class="number">1</span>,dis[x][y]=u.w+<span class="number">1</span>,q.push(Node(x,y,u.w+<span class="number">1</span>));</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> ans=<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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;++j) ans+=dis[i][j];</span><br><span class="line"> <span class="keyword">return</span> ans;</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"> freopen(<span class="string">"program4.in"</span>,<span class="string">"r"</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> freopen(<span class="string">"program4.out"</span>,<span class="string">"w"</span>,<span class="built_in">stdout</span>);</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&seed);</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">10</span>;++i) {</span><br><span class="line"> generate_input();</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,type==<span class="number">1</span>?count2():count1());</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><h4 id="答案-3"><a href="#答案-3" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">65300</span></span><br><span class="line"><span class="number">768644095452</span></span><br><span class="line"><span class="number">1614752</span></span><br><span class="line"><span class="number">12299725860312</span></span><br><span class="line"><span class="number">6474661</span></span><br><span class="line"><span class="number">480452490358302</span></span><br><span class="line"><span class="number">40508992</span></span><br><span class="line"><span class="number">480453060258360</span></span><br><span class="line"><span class="number">40509116</span></span><br><span class="line"><span class="number">40508835</span></span><br></pre></td></tr></table></figure><h3 id="Program-5"><a href="#Program-5" class="headerlink" title="Program 5"></a>Program 5</h3><h4 id="分析-4"><a href="#分析-4" class="headerlink" title="分析"></a>分析</h4><p>源代码中的 $\text{count3}$ 函数就是在寻找有多少个全 $1$ 子矩阵。很显然是<strong>单调栈</strong>裸题。我们逐行分析,对于当前行维护每个点往上的最大全 $1$ 长度 $h_i$,求出 $h_i$ 左边第一个大于它的位置 $l_i$,右边第一个大于等于它的位置 $r_i$,那么对答案的贡献为 $h_i\times (i-l_i+1)(r_i-i+1)$。</p><h4 id="代码-4"><a href="#代码-4" class="headerlink" title="代码"></a>代码</h4><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><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">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"><algorithm></span></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">5e3</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> n,m,seed,tp,h[N][N],l[N],r[N],st[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">next_rand</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">static</span> <span class="keyword">const</span> <span class="keyword">int</span> P=<span class="number">1000000007</span>,Q=<span class="number">83978833</span>,R=<span class="number">8523467</span>;</span><br><span class="line"> <span class="keyword">return</span> seed=((<span class="keyword">long</span> <span class="keyword">long</span>)Q*seed%P*seed+R)%P;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</span> <span class="title">calc</span><span class="params">(<span class="keyword">int</span> *a,<span class="keyword">int</span> n)</span> </span>{</span><br><span class="line"> st[tp=<span class="number">0</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">1</span>;i<=n;++i) {</span><br><span class="line"> <span class="keyword">for</span>(;tp&&a[i]<=a[st[tp]];--tp);</span><br><span class="line"> l[i]=st[tp]+<span class="number">1</span>;</span><br><span class="line"> st[++tp]=i;</span><br><span class="line"> }</span><br><span class="line"> st[tp=<span class="number">0</span>]=n+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n;i>=<span class="number">1</span>;--i) {</span><br><span class="line"> <span class="keyword">for</span>(;tp&&a[i]<a[st[tp]];--tp);</span><br><span class="line"> r[i]=st[tp]<span class="number">-1</span>;</span><br><span class="line"> st[++tp]=i;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> ans=<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"> ans+=<span class="number">1L</span>L*a[i]*(i-l[i]+<span class="number">1</span>)*(r[i]-i+<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">long</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,&m);</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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=m;++j) {</span><br><span class="line"> h[i][j]=(next_rand()%<span class="number">8</span>><span class="number">0</span>?h[i<span class="number">-1</span>][j]+<span class="number">1</span>:<span class="number">0</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> ans=<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) ans+=calc(h[i],m);</span><br><span class="line"> <span class="keyword">return</span> ans;</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"> freopen(<span class="string">"program5.in"</span>,<span class="string">"r"</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> freopen(<span class="string">"program5.out"</span>,<span class="string">"w"</span>,<span class="built_in">stdout</span>);</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&seed);</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">10</span>;++i) {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,solve());</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h4 id="答案-4"><a href="#答案-4" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">36798</span></span><br><span class="line"><span class="number">780109</span></span><br><span class="line"><span class="number">4970330</span></span><br><span class="line"><span class="number">19778353</span></span><br><span class="line"><span class="number">79444881</span></span><br><span class="line"><span class="number">183972917</span></span><br><span class="line"><span class="number">324090457</span></span><br><span class="line"><span class="number">401682783</span></span><br><span class="line"><span class="number">493647857</span></span><br><span class="line"><span class="number">493666110</span></span><br></pre></td></tr></table></figure><h3 id="Program-6"><a href="#Program-6" class="headerlink" title="Program 6"></a>Program 6</h3><h4 id="分析-5"><a href="#分析-5" class="headerlink" title="分析"></a>分析</h4><p>乍一看就是求 $f(f(f(\dots f(t))))$ 对 $c$ 取模,这个东西貌似是有环的?于是我们考虑找环,也就是找到这个<strong>环的起点</strong>。</p><p>我们可以使用 $\text{Floyd}$ <strong>判环算法</strong>,这个过程和 $\text{Pollard-Rho}$ 算法的实现很相似。因为这个环一定长成类似 $\rho$ 的形状。</p><p>我们设环长为 $n$,环之前的链长为 $m$,考虑使用<strong>两个指针</strong>,一个<strong>慢指针</strong>每次前进一步,一个<strong>快指针</strong>每次前进两步。两者都从起始点出发,当他们第一次相遇时一定有:</p><ul><li>慢指针移动了 $m+k_1 n+r$ 步。</li><li>快指针移动了 $m+k_2 n+r$ 步。</li></ul><p>由于快指针的速度是慢指针的两倍,那么设慢指针走了 $S$ 步,快指针走了 $2S$ 步,两式相减得到:</p><script type="math/tex; mode=display">S=(k_2-k_1)n</script><p>这意味着他们走过的路程都是<strong>环长的若干倍</strong>。</p><p>接下来我们把慢指针移动到起始位置,让两个指针都只移动一步,当慢指针移动了 $m$ 步,快指针总共移动了 $2S+m$ 步。对这个 $2S+m$ 有如下分析:</p><ol><li>计算出这个值:快指针和慢指针速度相同,都移动了 $m$ 的距离,加上之前的 $2S$ 就是 $2S+m$ 步。</li><li>换个角度思考:从起始位置走 $m$ 步到达环的起点,由于 $2S$ 是环长的整数倍,那么一定又走到了环的起点!</li></ol><p>这样一来我们就得到了环的起点!</p><p>当然本题可以用更加优秀的 $\text{Brent}$ 算法。</p><p><del>这个环长貌似是期望 $\sqrt c$ 的代?码只要十分钟就可以跑出来了!</del></p><h4 id="代码-5"><a href="#代码-5" class="headerlink" title="代码"></a>代码</h4><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="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"><cstdio></span></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> ull;</span><br><span class="line">ull n,a,b,c;</span><br><span class="line"></span><br><span class="line"><span class="function">ull <span class="title">F</span><span class="params">(ull x)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> (x*x*a+b)%c;</span><br><span class="line">}</span><br><span class="line"><span class="function">ull <span class="title">calcChain</span><span class="params">(ull x,ull &y)</span> </span>{</span><br><span class="line"> ull len=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(x!=y) x=F(x),y=F(F(y)),++len;</span><br><span class="line"> <span class="keyword">return</span> len;</span><br><span class="line">}</span><br><span class="line"><span class="function">ull <span class="title">calcLoop</span><span class="params">(ull x)</span> </span>{</span><br><span class="line"> ull st=x,len=<span class="number">1</span>;</span><br><span class="line"> x=F(x);</span><br><span class="line"> <span class="keyword">while</span>(x!=st) x=F(x),++len;</span><br><span class="line"> <span class="keyword">return</span> len;</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"> ull x=F(<span class="number">0</span>),y=F(F(<span class="number">0</span>));</span><br><span class="line"> <span class="keyword">while</span>(x!=y) x=F(x),y=F(F(y));</span><br><span class="line"> ull m=calcChain(<span class="number">0</span>,y);</span><br><span class="line"> ull len=calcLoop(y);</span><br><span class="line"> <span class="keyword">if</span>(n<m) {</span><br><span class="line"> ull ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(ull i=<span class="number">1</span>;i<=n;++i) ans=F(ans);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%llu\n"</span>,ans);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> n-=m;</span><br><span class="line"> ull ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(ull i=<span class="number">1</span>;i<=m;++i) ans=F(ans);</span><br><span class="line"> <span class="keyword">for</span>(ull i=<span class="number">1</span>;i<=n%len;++i) ans=F(ans);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%llu\n"</span>,ans);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</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"> freopen(<span class="string">"program6.in"</span>,<span class="string">"r"</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> freopen(<span class="string">"program6.out"</span>,<span class="string">"w"</span>,<span class="built_in">stdout</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">10</span>;++i) {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%llu%llu%llu%llu"</span>,&n,&a,&b,&c);</span><br><span class="line"> solve();</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><h4 id="答案-5"><a href="#答案-5" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">518048760868869048</span></span><br><span class="line"><span class="number">1792066212437514363</span></span><br><span class="line"><span class="number">31017889126204134</span></span><br><span class="line"><span class="number">2107151525961152753</span></span><br><span class="line"><span class="number">402987993063476955</span></span><br><span class="line"><span class="number">1026935915030784632</span></span><br><span class="line"><span class="number">2533709394548916391</span></span><br><span class="line"><span class="number">1357484894607415330</span></span><br><span class="line"><span class="number">1099871450072879095</span></span><br><span class="line"><span class="number">235900336338336004</span></span><br></pre></td></tr></table></figure><h3 id="Program-7"><a href="#Program-7" class="headerlink" title="Program 7"></a>Program 7</h3><h4 id="分析-6"><a href="#分析-6" class="headerlink" title="分析"></a>分析</h4><p>完成一个 $16\times 16$ 的数独<del>(字母独)</del>。</p><p>加上一些剪枝可以轻松跑出来前几个数独,最后几个数独需要采用<strong>倒搜</strong>。</p><h4 id="代码-6"><a href="#代码-6" class="headerlink" title="代码"></a>代码</h4><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><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">include</span> <span class="meta-string"><cstring></span></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">20</span>;</span><br><span class="line"><span class="keyword">char</span> s[N][N];</span><br><span class="line"><span class="keyword">bool</span> row[N][N],col[N][N],seq[N][N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">getSeq</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">int</span> r=x/<span class="number">4</span>+<span class="number">1</span>,c=y/<span class="number">4</span>+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span> (r<span class="number">-1</span>)*<span class="number">4</span>+c;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">dfs</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">if</span>(x<<span class="number">0</span>) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(s[x][y]!=<span class="string">'?'</span>) <span class="keyword">return</span> y==<span class="number">0</span>?dfs(x<span class="number">-1</span>,<span class="number">15</span>):dfs(x,y<span class="number">-1</span>);</span><br><span class="line"> <span class="keyword">int</span> z=getSeq(x,y);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">char</span> i=<span class="string">'A'</span>;i<=<span class="string">'P'</span>;++i) {</span><br><span class="line"> <span class="keyword">if</span>(row[x][i-<span class="string">'A'</span>]||col[y][i-<span class="string">'A'</span>]||seq[z][i-<span class="string">'A'</span>]) <span class="keyword">continue</span>;</span><br><span class="line"> row[x][i-<span class="string">'A'</span>]=col[y][i-<span class="string">'A'</span>]=seq[z][i-<span class="string">'A'</span>]=<span class="number">1</span>;</span><br><span class="line"> s[x][y]=i;</span><br><span class="line"> <span class="keyword">if</span>(y==<span class="number">0</span>?dfs(x<span class="number">-1</span>,<span class="number">15</span>):dfs(x,y<span class="number">-1</span>)) <span class="keyword">return</span> <span class="number">1</span>;</span><br><span class="line"> row[x][i-<span class="string">'A'</span>]=col[y][i-<span class="string">'A'</span>]=seq[z][i-<span class="string">'A'</span>]=<span class="number">0</span>;</span><br><span class="line"> s[x][y]=<span class="string">'?'</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 class="function"><span class="keyword">void</span> <span class="title">solve</span><span class="params">(<span class="keyword">int</span> points)</span> </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">15</span>;++i) <span class="built_in">scanf</span>(<span class="string">"%s"</span>,s[i]);</span><br><span class="line"> <span class="built_in">memset</span>(row,<span class="number">0</span>,<span class="keyword">sizeof</span>(row));</span><br><span class="line"> <span class="built_in">memset</span>(col,<span class="number">0</span>,<span class="keyword">sizeof</span>(col));</span><br><span class="line"> <span class="built_in">memset</span>(seq,<span class="number">0</span>,<span class="keyword">sizeof</span>(seq));</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">15</span>;++i) <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j<=<span class="number">15</span>;++j) <span class="keyword">if</span>(s[i][j]!=<span class="string">'?'</span>) {</span><br><span class="line"> row[i][s[i][j]-<span class="string">'A'</span>]=<span class="number">1</span>,col[j][s[i][j]-<span class="string">'A'</span>]=<span class="number">1</span>,seq[getSeq(i,j)][s[i][j]-<span class="string">'A'</span>]=<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(dfs(<span class="number">15</span>,<span class="number">15</span>)) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=<span class="number">1</span>;k<=points;++k,<span class="built_in">puts</span>(<span class="string">""</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">15</span>;++i) <span class="built_in">printf</span>(<span class="string">"%s"</span>,s[i]);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=<span class="number">1</span>;k<=points;++k) <span class="built_in">puts</span>(<span class="string">"NO SOLUTION"</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"> freopen(<span class="string">"program7.in"</span>,<span class="string">"r"</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> freopen(<span class="string">"program7.out"</span>,<span class="string">"w"</span>,<span class="built_in">stdout</span>);</span><br><span class="line"> solve(<span class="number">1</span>);</span><br><span class="line"> solve(<span class="number">2</span>);</span><br><span class="line"> solve(<span class="number">3</span>);</span><br><span class="line"> solve(<span class="number">4</span>);</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><h4 id="答案-6"><a href="#答案-6" class="headerlink" title="答案"></a>答案</h4><figure class="highlight armasm"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">NAPILFJBMHEOGDCKJDCHMNIPAFGKOBLEKLMGAEHONCDBPJFIFEOBCDGKIJLPAMHNOFHLJMBGEKIDCNAPPCEAHLDFBMJNIKGOBNIKOAPEFGCHJLMDMGDJNIKCLOPAFHEBIOBPFKLJHEMGDANCDKJEIGMAOBNCLFPHGMNCEPOHDLAFKIBJAHLFDBCNPIKJEGOMEIFMBHADKPOLNCJGHPADGJFICNBEMOKLLJKOPCNMGAHIBEDFCBGNKOELJDFMHPIA</span></span><br><span class="line"><span class="keyword">BLNOMGAPIHJKDCEFHGIMCFBOAPEDKNLJFCAEDKLJBGNOPHMIDKJPHIENFMLCGBAOIBEAKCFLHNOGJMDPLHFNJAPDCIKMEGOBPDOJNMHGELBFAKICCMGKOBIEJADPFLNHOFCHPNMBKJAELIGDJNLDGECHOBFIMPKAGAPIFDOKLCMNHJBEMEKBALJIGDPHOFCNEIBGLPNMDOHJCAFKKPDCEHGANFILBOJMNJHLBOKFMECAIDPGAOMFIJDCPKGBNEHL</span></span><br><span class="line"><span class="keyword">BLNOMGAPIHJKDCEFHGIMCFBOAPEDKNLJFCAEDKLJBGNOPHMIDKJPHIENFMLCGBAOIBEAKCFLHNOGJMDPLHFNJAPDCIKMEGOBPDOJNMHGELBFAKICCMGKOBIEJADPFLNHOFCHPNMBKJAELIGDJNLDGECHOBFIMPKAGAPIFDOKLCMNHJBEMEKBALJIGDPHOFCNEIBGLPNMDOHJCAFKKPDCEHGANFILBOJMNJHLBOKFMECAIDPGAOMFIJDCPKGBNEHL</span></span><br><span class="line"><span class="keyword">FMPCJGLEANDBOHKIOEHGNCAMFKILDJPBDBNIFHKPJOGEMACLKALJOIDBCHMPGNEFEGOHPJBKIFNMADLCALFDIENOHJKCBMGPNKCPMFGDBLEAHIJOJIBMHACLODPGEFNKLDIEAPHGNBCOJKFMMHAODLJCPGFKNBIEGPKFEBMNDIAJLCOHBCJNKOFIMELHPGADIOGKCDEHLABNFPMJPFEBLMIAGCJDKOHNHJDLGNPFKMOICEBACNMABKOJEPHFILDG</span></span><br><span class="line"><span class="keyword">FMPCJGLEANDBOHKIOEHGNCAMFKILDJPBDBNIFHKPJOGEMACLKALJOIDBCHMPGNEFEGOHPJBKIFNMADLCALFDIENOHJKCBMGPNKCPMFGDBLEAHIJOJIBMHACLODPGEFNKLDIEAPHGNBCOJKFMMHAODLJCPGFKNBIEGPKFEBMNDIAJLCOHBCJNKOFIMELHPGADIOGKCDEHLABNFPMJPFEBLMIAGCJDKOHNHJDLGNPFKMOICEBACNMABKOJEPHFILDG</span></span><br><span class="line"><span class="keyword">FMPCJGLEANDBOHKIOEHGNCAMFKILDJPBDBNIFHKPJOGEMACLKALJOIDBCHMPGNEFEGOHPJBKIFNMADLCALFDIENOHJKCBMGPNKCPMFGDBLEAHIJOJIBMHACLODPGEFNKLDIEAPHGNBCOJKFMMHAODLJCPGFKNBIEGPKFEBMNDIAJLCOHBCJNKOFIMELHPGADIOGKCDEHLABNFPMJPFEBLMIAGCJDKOHNHJDLGNPFKMOICEBACNMABKOJEPHFILDG</span></span><br><span class="line"><span class="keyword">LDFABIOEGCKJNMHPJPONCFDMLHABIGKEHMEGLJPKFNOIACDBCIKBANHGPMEDFOJLFBMIJPLHAKGEDNCOACJKODIFNLPHBEMGPGHEMBKNDFCOJILAONLDEAGCIJBMPHFKDJIPHOELCAFNGKBMEOGHPMCABIJKLDNFMFACNKJBOGDLEPIHBKNLIGFDMEHPCAOJILCJGHMPKBNAOFEDGHBFDLNOEPMCKJAINAPOKEBJHDIFMLGCKEDMFCAIJOLGHBPN</span></span><br><span class="line"><span class="keyword">LDFABIOEGCKJNMHPJPONCFDMLHABIGKEHMEGLJPKFNOIACDBCIKBANHGPMEDFOJLFBMIJPLHAKGEDNCOACJKODIFNLPHBEMGPGHEMBKNDFCOJILAONLDEAGCIJBMPHFKDJIPHOELCAFNGKBMEOGHPMCABIJKLDNFMFACNKJBOGDLEPIHBKNLIGFDMEHPCAOJILCJGHMPKBNAOFEDGHBFDLNOEPMCKJAINAPOKEBJHDIFMLGCKEDMFCAIJOLGHBPN</span></span><br><span class="line"><span class="keyword">LDFABIOEGCKJNMHPJPONCFDMLHABIGKEHMEGLJPKFNOIACDBCIKBANHGPMEDFOJLFBMIJPLHAKGEDNCOACJKODIFNLPHBEMGPGHEMBKNDFCOJILAONLDEAGCIJBMPHFKDJIPHOELCAFNGKBMEOGHPMCABIJKLDNFMFACNKJBOGDLEPIHBKNLIGFDMEHPCAOJILCJGHMPKBNAOFEDGHBFDLNOEPMCKJAINAPOKEBJHDIFMLGCKEDMFCAIJOLGHBPN</span></span><br><span class="line"><span class="keyword">LDFABIOEGCKJNMHPJPONCFDMLHABIGKEHMEGLJPKFNOIACDBCIKBANHGPMEDFOJLFBMIJPLHAKGEDNCOACJKODIFNLPHBEMGPGHEMBKNDFCOJILAONLDEAGCIJBMPHFKDJIPHOELCAFNGKBMEOGHPMCABIJKLDNFMFACNKJBOGDLEPIHBKNLIGFDMEHPCAOJILCJGHMPKBNAOFEDGHBFDLNOEPMCKJAINAPOKEBJHDIFMLGCKEDMFCAIJOLGHBPN</span></span><br></pre></td></tr></table></figure><h3 id="Program-8"><a href="#Program-8" class="headerlink" title="Program 8"></a>Program 8</h3><h4 id="分析-7"><a href="#分析-7" class="headerlink" title="分析"></a>分析</h4><p>我们发现这个代码本质就是求,对于所有的整数 $a,b,c,d,e,f,g\in [1,n]$,满足各种奇淫不等式的七元组有几个?</p><p>由于有 $7$ 个未知数,那么答案一定是关于 $n$ 的一个 $7$ 次多项式。可以暴力跑出来 $n\in [1,8]$ 的答案,然后<strong>拉格朗日插值</strong>即可。</p><h4 id="代码-7"><a href="#代码-7" class="headerlink" title="代码"></a>代码</h4><p>此处不放出具体代码了,拉格朗日插值的写法详见<a href="https://orzsiyuan.com/articles/algorithm-Lagrange-Interpolation" target="_blank" rel="noopener">「算法笔记」拉格朗日插值</a>。</p><h4 id="答案-7"><a href="#答案-7" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1018333390</span></span><br><span class="line"><span class="number">993704934</span></span><br><span class="line"><span class="number">1053807588</span></span><br><span class="line"><span class="number">1144151985</span></span><br><span class="line"><span class="number">712062141</span></span><br><span class="line"><span class="number">530076748</span></span><br><span class="line"><span class="number">520686243</span></span><br><span class="line"><span class="number">337499021</span></span><br><span class="line"><span class="number">820275783</span>同询问 $<span class="number">5</span>$,`hold`。</span><br><span class="line"><span class="number">80253986</span></span><br></pre></td></tr></table></figure><h3 id="Program-9"><a href="#Program-9" class="headerlink" title="Program 9"></a>Program 9</h3><h3 id="分析-8"><a href="#分析-8" class="headerlink" title="分析"></a>分析</h3><ol><li>答案为 $1984$。</li><li>常用密码 $123456$。</li><li><del>我怎么知道这个人是</del> <code>chenlijie</code>。</li><li>爆搜可以得到 <script type="math/tex">_</script>。</li><li>发现在 Program $2$ 中有一部伪英语字典,将其中每个单词的 $\text{MD5}$ 跑出来后和输入文件中的对比可以得到 <code>we</code>。</li><li>同询问 $5$,<code>hold</code>。</li><li>同询问 $5$,<code>these</code>。</li><li>同询问 $5$,<code>truths</code>。</li><li>由于最后一行的提示 <code>最后 6 行组成了一句名言</code>,可以在 Program $10$ 中找到这句话 <code>We hold these truths to be selfevident</code>。因此为 <code>to be</code>。</li><li>同询问 $9$,<code>selfevident</code>。</li></ol><h4 id="代码-8"><a href="#代码-8" class="headerlink" title="代码"></a>代码</h4><p><del>要什么代码?QAQ</del></p><h4 id="答案-8"><a href="#答案-8" class="headerlink" title="答案"></a>答案</h4><figure class="highlight autoit"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">1984</span></span><br><span class="line"><span class="number">123456</span></span><br><span class="line">chenlijie</span><br><span class="line">$_$</span><br><span class="line">we</span><br><span class="line">hold</span><br><span class="line">these</span><br><span class="line">truths</span><br><span class="line"><span class="keyword">to</span> be</span><br><span class="line">selfevident</span><br></pre></td></tr></table></figure><h3 id="Program-10"><a href="#Program-10" class="headerlink" title="Program 10"></a>Program 10</h3><h4 id="分析-9"><a href="#分析-9" class="headerlink" title="分析"></a>分析</h4><p>发现每个单词的函数运行时间不长,而瓶颈主要在 <code>A</code> 到 <code>Z</code> 函数。而他们的本质就是执行若干次 <code>_</code> 函数,直接<strong>递推</strong>出这些函数分别执行了多少次 <code>_</code> 即可。</p><h4 id="代码-9"><a href="#代码-9" class="headerlink" title="代码"></a>代码</h4><p><del>这么长代码放上来干嘛?QAQ</del></p><h4 id="答案-9"><a href="#答案-9" class="headerlink" title="答案"></a>答案</h4><figure class="highlight lsl"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">6754098618987872142</span></span><br><span class="line"><span class="number">3227259651709640332</span></span><br><span class="line"><span class="number">3227259651709640332</span></span><br><span class="line"><span class="number">1514994897561930504</span></span><br><span class="line"><span class="number">1514994897561930504</span></span><br><span class="line"><span class="number">9307175031877652086</span></span><br><span class="line"><span class="number">9307175031877652086</span></span><br><span class="line"><span class="number">9307175031877652086</span></span><br><span class="line"><span class="number">9307175031877652086</span></span><br><span class="line"><span class="number">9307175031877652086</span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="http://uoj.ac/problem/73" target="_blank" rel="noopener">UOJ 73</a></p>
</blockquote>
<p>本题是一道提交答案题,一共有 $10$ 个测试点。</p>
<p>对于每个测试点,你会得到一段程序的源代码和这段程序的输入。你要运行这个程序,并保存这个程序的输出。</p>
<p>遗憾的是这些程序效率都极其低下,无法在比赛的 $5$ 小时内得到输出。</p>
<p>你需要帮助 B 君得到这些程序的输出。</p>
<p><a href="http://uoj.ac/download.php?type=problem&amp;id=73" target="_blank" rel="noopener">输入数据下载</a></p>
</summary>
<category term="拉格朗日插值" scheme="http://hydingsy.github.io/tags/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E6%8F%92%E5%80%BC/"/>
<category term="UOJ" scheme="http://hydingsy.github.io/tags/UOJ/"/>
<category term="单调栈" scheme="http://hydingsy.github.io/tags/%E5%8D%95%E8%B0%83%E6%A0%88/"/>
<category term="BFS" scheme="http://hydingsy.github.io/tags/BFS/"/>
<category term="矩阵快速幂" scheme="http://hydingsy.github.io/tags/%E7%9F%A9%E9%98%B5%E5%BF%AB%E9%80%9F%E5%B9%82/"/>
<category term="WC" scheme="http://hydingsy.github.io/tags/WC/"/>
<category term="提交答案题" scheme="http://hydingsy.github.io/tags/%E6%8F%90%E4%BA%A4%E7%AD%94%E6%A1%88%E9%A2%98/"/>
<category term="Floyd 判环算法" scheme="http://hydingsy.github.io/tags/Floyd-%E5%88%A4%E7%8E%AF%E7%AE%97%E6%B3%95/"/>
</entry>
<entry>
<title>「算法笔记」拉格朗日插值</title>
<link href="http://hydingsy.github.io/articles/algorithm-Lagrange-Interpolation/"/>
<id>http://hydingsy.github.io/articles/algorithm-Lagrange-Interpolation/</id>
<published>2019-02-25T16:00:00.000Z</published>
<updated>2019-03-03T02:16:45.548Z</updated>
<content type="html"><![CDATA[<blockquote class="blockquote-center">如果对实践中的某个物理量进行观测,在若干个不同的地方得到相应的观测值,拉格朗日插值法可以找到一个多项式,其恰好在各个观测的点取到观测到的值。</blockquote><a id="more"></a><h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>众所周知,平面上 $n+1$ 个点可以确定一个 $n$ 次多项式 $P(x)$。现在已知 $n+1$ 个点 $(x_i,y_i)$,请确定经过这 $n+1$ 个点的多项式 $P(x)$ 在 $x=k$ 时的值。</p><p>拉格朗日插值可以解决这类问题!</p><hr><h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><p>拉格朗日插值的经精妙之处就在于<strong>拉格朗日基本多项式</strong>。</p><p>我们设这 $n$ 个点为 $(x_0,y_0),(x_1,y_1),\dots,(x_n,y_n)$。那么我们构造多项式:</p><script type="math/tex; mode=display">\ell_i(x)=\prod_{j=0,i\neq j}^n \frac{k-x_j}{x_i-x_j}</script><p>这个多项式的构造十分巧妙,我们可以注意到如下规律:</p><script type="math/tex; mode=display">\ell_i(x_j)=\begin{cases}1 & i=j \\0 & i\neq j\end{cases}</script><p>接着我们构造这个 $n$ 次多项式:</p><script type="math/tex; mode=display">P(x)=\sum_{i=0}^n y_i\ell_i(x)</script><p>根据基本多项式的性质,我们可以得到 $P(x_i)=y_i$,也就是说保证经过这 $n+1$ 个点,经过简单的计算就可以得到<strong>系数表达式</strong>,当然也很容易得到 $P(k)$ 的值了。</p><p><strong>时间复杂度</strong>:$O(n^2)$</p><hr><h2 id="拓展"><a href="#拓展" class="headerlink" title="拓展"></a>拓展</h2><h3 id="取值连续"><a href="#取值连续" class="headerlink" title="取值连续"></a>取值连续</h3><p>考虑在 $x$ 的值连续的情况下,如何快速求 $P(k)$ 的值?(这里的 $x$ 的值连续的意思是:对于 $0\le i\le n$,$x_i=i$)</p><p>那么式子化为:</p><script type="math/tex; mode=display">P(x)=\sum_{i=0}^n y_i\prod_{j=0,i\neq j}^n \frac{x-j}{i-j}</script><p>对于分子,我们维护 $pre_i=\prod_{j=0}^i k-j$,$suf_i=\prod_{j=i}^n k-j$;而对于分母,我们发现就是阶乘的形式!于是这个式子变成了:</p><script type="math/tex; mode=display">P(k)=\sum_{i=0}^n y_i\frac{pre_{i-1}\cdot suf_{i+1}}{i!\cdot (n-i)!}</script><p>但是注意:分母可能出现符号问题,也就是说说当 $n-i$ 为负数时,分母应该取<strong>负号</strong>!</p><p><strong>时间复杂度</strong>:$O(n)$</p><h3 id="经典应用"><a href="#经典应用" class="headerlink" title="经典应用"></a>经典应用</h3><p>求解 $1$ 到 $n$ 的 $k$ 次方和。即如下式子:</p><script type="math/tex; mode=display">\sum_{i=1}^n i^k</script><p>数据范围:$1\le n\le 10^{18}$,$1\le k\le 10^6$</p><p>这个东西显然是一个以 $n$ 为自变量的 $k+1$ 次多项式。那么我们代入 $1\sim k+2$ 这一共 $k+2$ 个点后直接拉格朗日插值即可!</p><blockquote><p><strong>定理</strong>:若多项式 $P(x)$ 的次数为 $n$,那么对于任何 $k\ge n+1$,多项式 $P(x)$ 的 $k$ 阶差分恒等于 $0$。</p></blockquote><p>我们预处理出 $pre_i$ 和 $suf_i$,在处理 $k+2$ 个点时可以采用<strong>线性筛</strong>求出每个数的 $k$ 次方。</p><p><strong>时间复杂度</strong>:$O(k)$</p><hr><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><p>我们用一个函数 $\text{lagrange}$ 来实现。其中 <code>*x,*y</code> 分别存点的坐标,函数的返回值为 $P(k)$ 的值(其中 $\text{mod}$ 为模数,$\text{inv}(x)$ 表示 $x$ 的逆元,$\text{upd}(x,y)$ 表示将 $x$ 加上 $y$)。</p><h3 id="常用写法"><a href="#常用写法" class="headerlink" title="常用写法"></a>常用写法</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">lagrange</span><span class="params">(<span class="keyword">int</span> n,<span class="keyword">int</span> *x,<span class="keyword">int</span> *y,<span class="keyword">int</span> k)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<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">int</span> f=<span class="number">1</span>,g=<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<=n;++j) <span class="keyword">if</span>(i!=j) {</span><br><span class="line"> f=<span class="number">1L</span>L*f*(k-x[j]+mod)%mod;</span><br><span class="line"> g=<span class="number">1L</span>L*g*(x[i]-x[j]+mod)%mod;</span><br><span class="line"> }</span><br><span class="line"> upd(ans,<span class="number">1L</span>L*y[i]*f%mod*inv(g)%mod);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="取值连续-1"><a href="#取值连续-1" class="headerlink" title="取值连续"></a>取值连续</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">lagrange</span><span class="params">(<span class="keyword">int</span> n,<span class="keyword">int</span> *y,<span class="keyword">int</span> k)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">0</span>;</span><br><span class="line"> pre[<span class="number">0</span>]=suf[n+<span class="number">1</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<=n;++i) pre[i]=<span class="number">1L</span>L*pre[i<span class="number">-1</span>]*(k-i)%mod;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n;i>=<span class="number">1</span>;--i) suf[i]=<span class="number">1L</span>L*suf[i+<span class="number">1</span>]*(k-i)%mod;</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">int</span> a=<span class="number">1L</span>L*pre[i<span class="number">-1</span>]*suf[i+<span class="number">1</span>]%mod*inv[i<span class="number">-1</span>]%mod*inv[n-i]%mod;</span><br><span class="line"> <span class="keyword">if</span>((n-i)&<span class="number">1</span>) a=mod-a;</span><br><span class="line"> upd(ans,<span class="number">1L</span>L*a*y[i]%mod);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><hr><h2 id="习题"><a href="#习题" class="headerlink" title="习题"></a>习题</h2><ul><li><a href="https://www.luogu.org/problemnew/show/P4781" target="_blank" rel="noopener">「Luogu 4781」【模板】拉格朗日插值</a></li><li><a href="http://www.51nod.com/Challenge/Problem.html#!#problemId=1228" target="_blank" rel="noopener">「51nod 1228」序列求和 V1</a></li><li><a href="http://www.51nod.com/Challenge/Problem.html#!#problemId=1258" target="_blank" rel="noopener">「51nod 1258」序列求和 V4</a></li><li><a href="https://www.lydsy.com/JudgeOnline/problem.php?id=5339" target="_blank" rel="noopener">「TJOI 2018」教科书般的亵渎</a></li><li><a href="https://www.lydsy.com/JudgeOnline/problem.php?id=3453" target="_blank" rel="noopener">「BZOJ 3453」XLKxc</a></li><li><a href="https://www.lydsy.com/JudgeOnline/problem.php?id=4559" target="_blank" rel="noopener">「JLOI 2016」成绩比较</a></li><li><a href="https://www.lydsy.com/JudgeOnline/problem.php?id=2655" target="_blank" rel="noopener">「BZOJ 2655」Calc</a></li></ul>]]></content>
<summary type="html">
<blockquote class="blockquote-center">如果对实践中的某个物理量进行观测,在若干个不同的地方得到相应的观测值,拉格朗日插值法可以找到一个多项式,其恰好在各个观测的点取到观测到的值。</blockquote>
</summary>
<category term="算法笔记" scheme="http://hydingsy.github.io/tags/%E7%AE%97%E6%B3%95%E7%AC%94%E8%AE%B0/"/>
<category term="数论" scheme="http://hydingsy.github.io/tags/%E6%95%B0%E8%AE%BA/"/>
<category term="拉格朗日插值" scheme="http://hydingsy.github.io/tags/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E6%8F%92%E5%80%BC/"/>
</entry>
<entry>
<title>「Codeforces 1097D」Makoto and a Blackboard</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-1097D-Makoto-and-a-Blackboard/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-1097D-Makoto-and-a-Blackboard/</id>
<published>2019-02-24T16:00:00.000Z</published>
<updated>2019-02-28T04:04:06.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/1097/problem/D" target="_blank" rel="noopener">Codeforces 1097D</a></p></blockquote><p>Makoto 有一个大黑板,上面写着一个正整数 $n$,他将会进行恰好 $k$ 次操作:</p><p>假设黑板上的数字是 $v$,他会随机选择一个 $v$ 的约数(可能是 $1$ 或 $v$)然后用这个约数替换 $v$。保证每个约数被选择的概率相同。</p><p>他想知道 $k$ 次操作后黑板上的数字的期望值是多少。答案对 $10^9+7$ 取模。</p><p>数据范围:$1\le n\le 10^{15}$,$1\le k\le 10^4$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>我们定义 $f(i,j)$ 表示操作 $i$ 次后得到数字 $j$ 的概率。发现每个质因子都是<strong>相互独立</strong>的,每次改变的只不过是若干个<strong>质因子的指数</strong>。那么这意味着 $f$ 是一个<strong>积性函数</strong>!</p><p>考虑对于 $n$ 的一个质因子 $p$,其指数为 $c$,那么设 $g(i,j)$ 表示数字 $p^c$ 操作 $i$ 次后指数为 $j$ 的概率。转移方程为:</p><script type="math/tex; mode=display">g(i,j)=\sum_{k=j}^c \frac{g(i-1,k)}{k+1}</script><p>这个式子的含义是:指数 $j$ 可以由指数 $j\sim c$ 转移过来,对于原来的指数 $k$,有 $\frac{1}{k+1}$ 的概率转移到现在的指数 $j$(其实这个式子可以<strong>前缀和优化</strong>,复杂度由 $O(kc^2)$ 优化为 $O(kc)$,但是由于 $c\le \log n$,因此无关紧要)。</p><p>那么数字 $p^c$ 操作后的期望为:</p><script type="math/tex; mode=display">\sum_{i=0}^c g(k,i)\times p^i</script><p>最终的答案为所有质因子答案的<strong>乘积</strong>(积性函数的定义)。</p><p><strong>时间复杂度</strong>:$O(k\log^3 n)$(非常不满),优化后为 $O(k\log^2 n)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><h3 id="朴素写法"><a href="#朴素写法" class="headerlink" title="朴素写法"></a>朴素写法</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><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">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"><vector></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> K=<span class="number">1e4</span>+<span class="number">5</span>,logN=<span class="number">51</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod=<span class="number">1e9</span>+<span class="number">7</span>;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">long</span> n;</span><br><span class="line"><span class="keyword">int</span> k,f[K][logN],inv[logN];</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">vector</span><<span class="built_in">std</span>::pair<<span class="keyword">int</span>,<span class="keyword">int</span>> > v;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">getFactor</span><span class="params">(<span class="keyword">long</span> <span class="keyword">long</span> n)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">2</span>;<span class="number">1L</span>L*i*i<=n;++i) {</span><br><span class="line"> <span class="keyword">if</span>(n%i) <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">int</span> cnt=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(n%i==<span class="number">0</span>) n/=i,++cnt;</span><br><span class="line"> v.push_back(<span class="built_in">std</span>::make_pair(i,cnt));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(n><span class="number">1</span>) v.push_back(<span class="built_in">std</span>::make_pair(n%mod,<span class="number">1</span>));</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">initInv</span><span class="params">()</span> </span>{</span><br><span class="line"> inv[<span class="number">0</span>]=inv[<span class="number">1</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<logN;++i) inv[i]=<span class="number">1L</span>L*(mod-mod/i)*inv[mod%i]%mod;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">pow</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> p)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(;p;p>>=<span class="number">1</span>,x=<span class="number">1L</span>L*x*x%mod) <span class="keyword">if</span>(p&<span class="number">1</span>) ans=<span class="number">1L</span>L*ans*x%mod;</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">upd</span><span class="params">(<span class="keyword">int</span> &x,<span class="keyword">int</span> y)</span> </span>{</span><br><span class="line"> (x+=y)>=mod&&(x-=mod);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">solve</span><span class="params">(<span class="keyword">int</span> p,<span class="keyword">int</span> c)</span> </span>{</span><br><span class="line"> <span class="built_in">memset</span>(f,<span class="number">0</span>,<span class="keyword">sizeof</span>(f));</span><br><span class="line"> f[<span class="number">0</span>][c]=<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<=k;++i) <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j<=c;++j) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> l=j;l<=c;++l) upd(f[i][j],<span class="number">1L</span>L*f[i<span class="number">-1</span>][l]*inv[l+<span class="number">1</span>]%mod);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> ans=<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<=c;++i) upd(ans,<span class="number">1L</span>L*f[k][i]*<span class="built_in">pow</span>(p,i)%mod);</span><br><span class="line"> <span class="keyword">return</span> ans;</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%d"</span>,&n,&k);</span><br><span class="line"> getFactor(n);</span><br><span class="line"> initInv();</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="built_in">std</span>::pair<<span class="keyword">int</span>,<span class="keyword">int</span>> x:v) ans=<span class="number">1L</span>L*ans*solve(x.first,x.second)%mod;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,ans);</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><h3 id="前缀和优化"><a href="#前缀和优化" class="headerlink" title="前缀和优化"></a>前缀和优化</h3><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><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">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"><vector></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> logN=<span class="number">51</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod=<span class="number">1e9</span>+<span class="number">7</span>;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">long</span> n;</span><br><span class="line"><span class="keyword">int</span> k,f[logN],inv[logN],s[logN];</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">vector</span><<span class="built_in">std</span>::pair<<span class="keyword">int</span>,<span class="keyword">int</span>> > v;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">getFactor</span><span class="params">(<span class="keyword">long</span> <span class="keyword">long</span> n)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">2</span>;<span class="number">1L</span>L*i*i<=n;++i) {</span><br><span class="line"> <span class="keyword">if</span>(n%i) <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">int</span> cnt=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(n%i==<span class="number">0</span>) n/=i,++cnt;</span><br><span class="line"> v.push_back(<span class="built_in">std</span>::make_pair(i,cnt));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(n><span class="number">1</span>) v.push_back(<span class="built_in">std</span>::make_pair(n%mod,<span class="number">1</span>));</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">initInv</span><span class="params">()</span> </span>{</span><br><span class="line"> inv[<span class="number">0</span>]=inv[<span class="number">1</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<logN;++i) inv[i]=<span class="number">1L</span>L*(mod-mod/i)*inv[mod%i]%mod;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">pow</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> p)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(;p;p>>=<span class="number">1</span>,x=<span class="number">1L</span>L*x*x%mod) <span class="keyword">if</span>(p&<span class="number">1</span>) ans=<span class="number">1L</span>L*ans*x%mod;</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">upd</span><span class="params">(<span class="keyword">int</span> &x,<span class="keyword">int</span> y)</span> </span>{</span><br><span class="line"> (x+=y)>=mod&&(x-=mod);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">solve</span><span class="params">(<span class="keyword">int</span> p,<span class="keyword">int</span> c)</span> </span>{</span><br><span class="line"> <span class="built_in">memset</span>(f,<span class="number">0</span>,<span class="keyword">sizeof</span>(f)),<span class="built_in">memset</span>(s,<span class="number">0</span>,<span class="keyword">sizeof</span>(s));</span><br><span class="line"> f[c]=<span class="number">1</span>,s[c]=f[c]*inv[c+<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<=k;++i) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j<=c;++j) f[j]=(s[c]-(j?s[j<span class="number">-1</span>]:<span class="number">0</span>)+mod)%mod;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j<=c;++j) s[j]=<span class="number">1L</span>L*f[j]*inv[j+<span class="number">1</span>]%mod;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=c;++j) upd(s[j],s[j<span class="number">-1</span>]);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> ans=<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<=c;++i) upd(ans,<span class="number">1L</span>L*f[i]*<span class="built_in">pow</span>(p,i)%mod);</span><br><span class="line"> <span class="keyword">return</span> ans;</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%d"</span>,&n,&k);</span><br><span class="line"> getFactor(n);</span><br><span class="line"> initInv();</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="built_in">std</span>::pair<<span class="keyword">int</span>,<span class="keyword">int</span>> x:v) ans=<span class="number">1L</span>L*ans*solve(x.first,x.second)%mod;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,ans);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/1097/problem/D" target="_blank" rel="noopener">Codeforces 1097D</a></p>
</blockquote>
<p>Makoto 有一个大黑板,上面写着一个正整数 $n$,他将会进行恰好 $k$ 次操作:</p>
<p>假设黑板上的数字是 $v$,他会随机选择一个 $v$ 的约数(可能是 $1$ 或 $v$)然后用这个约数替换 $v$。保证每个约数被选择的概率相同。</p>
<p>他想知道 $k$ 次操作后黑板上的数字的期望值是多少。答案对 $10^9+7$ 取模。</p>
<p>数据范围:$1\le n\le 10^{15}$,$1\le k\le 10^4$</p>
</summary>
<category term="数论" scheme="http://hydingsy.github.io/tags/%E6%95%B0%E8%AE%BA/"/>
<category term="动态规划" scheme="http://hydingsy.github.io/tags/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="概率期望" scheme="http://hydingsy.github.io/tags/%E6%A6%82%E7%8E%87%E6%9C%9F%E6%9C%9B/"/>
<category term="积性函数" scheme="http://hydingsy.github.io/tags/%E7%A7%AF%E6%80%A7%E5%87%BD%E6%95%B0/"/>
</entry>
<entry>
<title>「Codeforces 498C」Array and Operations</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-498C-Array-and-Operations/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-498C-Array-and-Operations/</id>
<published>2019-02-24T16:00:00.000Z</published>
<updated>2019-03-03T02:18:59.666Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/498/problem/C" target="_blank" rel="noopener">Codeforces 498C</a></p></blockquote><p>你有一个长度为 $n$ 的正整数序列 $a_1,a_2,\dots,a_n$ 和 $m$ 对整数 $(i_1,j_1),(i_2,j_2),\dots,(i_m,j_m)$。每一对整数 $(i_k,j_k)$ 都满足 $i_k+j_k$ 的值是奇数,且 $1\le i_k<j_k\le n$。</p><p>每一次操作你可以进行一系列行为:</p><ol><li>在 $m$ 个数对中选择一个 $(i_k,j_k)$ 和一个整数 $v$ 满足 $v>1$,并且 $v$ 整除 $a_{i_k}$ 和 $a_{j_k}$。</li><li>将 $a_{i_k}$ 和 $a_{j_k}$ 都除以 $v$。</li></ol><p>请计算出能够进行的最大操作次数。注意,每一对数可能多次使用。</p><p>数据范围:$2\le n\le 100$,$1\le m\le 100$,$1\le a_i\le 10^9$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>首先注意到一个重要的性质:$i_k+j_k$ 为奇数。换言之,我们可以把原序列按照下标奇偶性<strong>分成两部分</strong>,下标为 $i_k$ 和 $j_k$ 的两个数一定不是同一个部分的。也就是说,如果我们在 $i_k$ 和 $j_k$ 之间连边,那么这是一张<strong>二分图</strong>。</p><p>我们建立出这张二分图,新建一个<strong>源点</strong>和<strong>汇点</strong>,每个点向源点或汇点连一条容量为 $\vert S_{a_i}\vert$ 的边(其中 $S_{i}$ 为 $i$ 的质因子可重集合,如 $12$ 的质因子集合为 $\{2,2,3\}$ ),$a_{i_k}$ 和 $a_{j_k}$ 之间的边的容量为 $\vert S_{a_{i_k}}\cap S_{a_{j_k}}\vert$(质因子集合交集大小)。</p><p>看起来直接跑<strong>最大流</strong>就行了?其实很容易找到反例。因为同一个数的质因子不是独立的,一旦被除去之后就不能被别的数字配对。那么我们可以想到<strong>拆点</strong>。</p><ul><li>对于数字 $x$,我们把他拆成<strong>质因子个数个点</strong>,每个质因子向源点或汇点连一条容量为其<strong>指数</strong>的边。</li><li>对于两个数字 $x,y$,我们定义代表的质因子相同的点性质相同。我们把 $x,y$ 性质相同的点连边,容量为这个质因子在 $x$ 和 $y$ 中指数的<strong>较小值</strong>。</li><li>直接跑最大流即可。</li></ul><p><strong>时间复杂度</strong>:$O(m\sqrt n)$,前面应该有一个较大常数,因为点最多有 $9n$ 个,边最多有 $9m$ 条。</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></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"><algorithm></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="keyword">typedef</span> <span class="built_in">std</span>::pair<<span class="keyword">int</span>,<span class="keyword">int</span>> pii;</span><br><span class="line"><span class="keyword">typedef</span> <span class="built_in">std</span>::pair<pii,<span class="keyword">int</span>> ppi;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N=<span class="number">2e3</span>+<span class="number">5</span>,M=<span class="number">2e5</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> n,m,idx,tot=<span class="number">1</span>,lnk[N],cnr[N],ter[M],nxt[M],val[M],dep[N];</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">vector</span><ppi> a[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> v,<span class="keyword">int</span> w)</span> </span>{</span><br><span class="line"> ter[++tot]=v,nxt[tot]=lnk[u],lnk[u]=tot,val[tot]=w;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">addedge</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> v,<span class="keyword">int</span> w)</span> </span>{</span><br><span class="line"> add(u,v,w),add(v,u,<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">bfs</span><span class="params">(<span class="keyword">int</span> s,<span class="keyword">int</span> t)</span> </span>{</span><br><span class="line"> <span class="built_in">memset</span>(dep,<span class="number">0</span>,<span class="keyword">sizeof</span>(dep));</span><br><span class="line"> <span class="built_in">memcpy</span>(cnr,lnk,<span class="keyword">sizeof</span>(lnk));</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">queue</span><<span class="keyword">int</span>> q;</span><br><span class="line"> q.push(s),dep[s]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(!q.empty()) {</span><br><span class="line"> <span class="keyword">int</span> u=q.front(); q.pop();</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(val[i]&&!dep[v]) q.push(v),dep[v]=dep[u]+<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> dep[t];</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> t,<span class="keyword">int</span> flow)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(u==t) <span class="keyword">return</span> flow;</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> &i=cnr[u];i&&ans<flow;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(val[i]&&dep[v]==dep[u]+<span class="number">1</span>) {</span><br><span class="line"> <span class="keyword">int</span> x=dfs(v,t,<span class="built_in">std</span>::min(val[i],flow-ans));</span><br><span class="line"> <span class="keyword">if</span>(x) val[i]-=x,val[i^<span class="number">1</span>]+=x,ans+=x;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(ans<flow) dep[u]=<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"><span class="keyword">int</span> <span class="title">dinic</span><span class="params">(<span class="keyword">int</span> s,<span class="keyword">int</span> t)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(bfs(s,t)) {</span><br><span class="line"> <span class="keyword">int</span> x;</span><br><span class="line"> <span class="keyword">while</span>((x=dfs(s,t,<span class="number">1</span><<<span class="number">30</span>))) ans+=x;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line">}</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">vector</span><ppi> solve(<span class="keyword">int</span> x) {</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">vector</span><ppi> ans;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">2</span>;i*i<=x;++i) {</span><br><span class="line"> <span class="keyword">if</span>(x%i) <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">int</span> cnt=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">while</span>(x%i==<span class="number">0</span>) x/=i,++cnt;</span><br><span class="line"> ans.push_back(ppi(pii(i,cnt),++idx));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>(x><span class="number">1</span>) ans.push_back(ppi(pii(x,<span class="number">1</span>),++idx));</span><br><span class="line"> <span class="keyword">return</span> ans;</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">"%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<=n;++i) {</span><br><span class="line"> <span class="keyword">int</span> x;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&x);</span><br><span class="line"> a[i]=solve(x);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">while</span>(m--) {</span><br><span class="line"> <span class="keyword">int</span> u,v;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&u,&v);</span><br><span class="line"> <span class="keyword">if</span>(v&<span class="number">1</span>) <span class="built_in">std</span>::swap(u,v);</span><br><span class="line"> <span class="keyword">for</span>(ppi x:a[u]) <span class="keyword">for</span>(ppi y:a[v]) {</span><br><span class="line"> <span class="keyword">if</span>(x.first.first==y.first.first) {</span><br><span class="line"> addedge(x.second,y.second,<span class="built_in">std</span>::min(x.first.second,y.first.second));</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> s=<span class="number">0</span>,t=idx+<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 class="number">2</span>) {</span><br><span class="line"> <span class="keyword">for</span>(ppi x:a[i]) addedge(s,x.second,x.first.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">2</span>;i<=n;i+=<span class="number">2</span>) {</span><br><span class="line"> <span class="keyword">for</span>(ppi x:a[i]) addedge(x.second,t,x.first.second);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> ans=dinic(s,t);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,ans);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/498/problem/C" target="_blank" rel="noopener">Codeforces 498C</a></p>
</blockquote>
<p>你有一个长度为 $n$ 的正整数序列 $a_1,a_2,\dots,a_n$ 和 $m$ 对整数 $(i_1,j_1),(i_2,j_2),\dots,(i_m,j_m)$。每一对整数 $(i_k,j_k)$ 都满足 $i_k+j_k$ 的值是奇数,且 $1\le i_k&lt;j_k\le n$。</p>
<p>每一次操作你可以进行一系列行为:</p>
<ol>
<li>在 $m$ 个数对中选择一个 $(i_k,j_k)$ 和一个整数 $v$ 满足 $v&gt;1$,并且 $v$ 整除 $a_{i_k}$ 和 $a_{j_k}$。</li>
<li>将 $a_{i_k}$ 和 $a_{j_k}$ 都除以 $v$。</li>
</ol>
<p>请计算出能够进行的最大操作次数。注意,每一对数可能多次使用。</p>
<p>数据范围:$2\le n\le 100$,$1\le m\le 100$,$1\le a_i\le 10^9$</p>
</summary>
<category term="图论" scheme="http://hydingsy.github.io/tags/%E5%9B%BE%E8%AE%BA/"/>
<category term="网络流" scheme="http://hydingsy.github.io/tags/%E7%BD%91%E7%BB%9C%E6%B5%81/"/>
<category term="最大流" scheme="http://hydingsy.github.io/tags/%E6%9C%80%E5%A4%A7%E6%B5%81/"/>
<category term="贪心" scheme="http://hydingsy.github.io/tags/%E8%B4%AA%E5%BF%83/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="二分图" scheme="http://hydingsy.github.io/tags/%E4%BA%8C%E5%88%86%E5%9B%BE/"/>
</entry>
<entry>
<title>「Ynoi 2015」我回来了</title>
<link href="http://hydingsy.github.io/articles/problem-Ynoi-2015-I-am-Back/"/>
<id>http://hydingsy.github.io/articles/problem-Ynoi-2015-I-am-Back/</id>
<published>2019-02-24T16:00:00.000Z</published>
<updated>2019-03-02T06:05:58.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://www.luogu.org/problemnew/show/P5068" target="_blank" rel="noopener">Luogu 5068</a></p></blockquote><p>珂朵莉给你一个 $n$ 个点,$m$ 条边的无向无权图,一共有 $q$ 次询问,每次询问的时候给一堆二元组 $(x_i,y_i)$ 求图中有多少个点 $u$ 与这次询问中至少一个二元组 $(x_i,y_i)$ 满足 $\text{dist}(u,x_i)\le y_i$,$\text{dist}$ 表示这两个点在图中的距离。如果不连通 $\text{dist}=\infin$。</p><p>数据范围:$1\le n\le 10^3$,$1\le m,q\le 10^5$,记二元组的个数和为 $a$ 则 $1\le a\le 2.1\times 10^6$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>我们对每个点 $i$ 和距离 $j$ 维护一个 $\text{bitset}\ f_{i,j}$ 表示和点 $i$ 距离不超过 $j$ 的点的集合。这个不超过可以用 $\text{bitset}$ 的<strong>前缀或</strong>得到。</p><p>询问时只需要把 $f_{x_i,y_i}$ 这些 $\text{bitset}$ 或起来,点集的大小就是答案。</p><p><strong>时间复杂度</strong>:$O(nm+\frac{n^3+an}{\omega})$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><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">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"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><bitset></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><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N=<span class="number">1e3</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> n,m,q,dis[N];</span><br><span class="line"><span class="keyword">bool</span> vis[N];</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">vector</span><<span class="keyword">int</span>> e[N];</span><br><span class="line"><span class="built_in">std</span>::<span class="built_in">bitset</span><N> f[N][N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">bfs</span><span class="params">(<span class="keyword">int</span> s)</span> </span>{</span><br><span class="line"> <span class="built_in">memset</span>(dis,<span class="number">0x3f</span>,<span class="keyword">sizeof</span>(dis));</span><br><span class="line"> <span class="built_in">memset</span>(vis,<span class="number">0</span>,<span class="keyword">sizeof</span>(vis));</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">queue</span><<span class="keyword">int</span>> q;</span><br><span class="line"> q.push(s),dis[s]=<span class="number">0</span>,vis[s]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">while</span>(!q.empty()) {</span><br><span class="line"> <span class="keyword">int</span> u=q.front(); q.pop();</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> v:e[u]) {</span><br><span class="line"> <span class="keyword">if</span>(!vis[v]) dis[v]=dis[u]+<span class="number">1</span>,vis[v]=<span class="number">1</span>,q.push(v);</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">void</span> <span class="title">init</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">1</span>;i<=n;++i) {</span><br><span class="line"> bfs(i);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) {</span><br><span class="line"> <span class="keyword">if</span>(dis[j]!=<span class="number">0x3f3f3f3f</span>) f[i][dis[j]][j]=<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) f[i][j]|=f[i][j<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">"%d%d%d"</span>,&n,&m,&q);</span><br><span class="line"> <span class="keyword">while</span>(m--) {</span><br><span class="line"> <span class="keyword">int</span> u,v;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&u,&v);</span><br><span class="line"> e[u].push_back(v),e[v].push_back(u);</span><br><span class="line"> }</span><br><span class="line"> init();</span><br><span class="line"> <span class="keyword">while</span>(q--) {</span><br><span class="line"> <span class="keyword">int</span> p;</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">bitset</span><N> ans;</span><br><span class="line"> <span class="keyword">for</span>(<span class="built_in">scanf</span>(<span class="string">"%d"</span>,&p);p--;) {</span><br><span class="line"> <span class="keyword">int</span> x,y;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&x,&y);</span><br><span class="line"> ans|=f[x][y>n?n:y];</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,(<span class="keyword">int</span>)ans.count());</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://www.luogu.org/problemnew/show/P5068" target="_blank" rel="noopener">Luogu 5068</a></p>
</blockquote>
<p>珂朵莉给你一个 $n$ 个点,$m$ 条边的无向无权图,一共有 $q$ 次询问,每次询问的时候给一堆二元组 $(x_i,y_i)$ 求图中有多少个点 $u$ 与这次询问中至少一个二元组 $(x_i,y_i)$ 满足 $\text{dist}(u,x_i)\le y_i$,$\text{dist}$ 表示这两个点在图中的距离。如果不连通 $\text{dist}=\infin$。</p>
<p>数据范围:$1\le n\le 10^3$,$1\le m,q\le 10^5$,记二元组的个数和为 $a$ 则 $1\le a\le 2.1\times 10^6$</p>
</summary>
<category term="图论" scheme="http://hydingsy.github.io/tags/%E5%9B%BE%E8%AE%BA/"/>
<category term="bitset" scheme="http://hydingsy.github.io/tags/bitset/"/>
<category term="Luogu" scheme="http://hydingsy.github.io/tags/Luogu/"/>
<category term="BFS" scheme="http://hydingsy.github.io/tags/BFS/"/>
<category term="最短路" scheme="http://hydingsy.github.io/tags/%E6%9C%80%E7%9F%AD%E8%B7%AF/"/>
</entry>
<entry>
<title>「Codeforces 593E」Strange Calculation and Cats</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-593E-Strange-Calculation-and-Cats/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-593E-Strange-Calculation-and-Cats/</id>
<published>2019-02-23T16:00:00.000Z</published>
<updated>2019-02-28T08:04:02.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/593/problem/E" target="_blank" rel="noopener">Codeforces 593E</a></p></blockquote><p>Gosha 的宇宙是一个由 $n$ 行 $m$ 列组成的表格。他经常被邀请去某个地方,每次接到邀请后,他会先计算到达那个地方的路径方案数,然后再动身出发。Gosha 的房子位于 $(1,1)$。</p><p>在任何时刻,Gosha 都会从当前格子到达相邻的格子,当然不会超出边界。此外,他也可以选择不移动而停留在当前格子里。</p><p>他除了喜欢奇怪的计算,还对猫过敏,因此他从来不去有猫的格子。Gosha 清楚地知道他何时何地会被邀请,也知道猫的在格子上的行程。形式化地讲,他有 $q$ 条记录,第 $i$ 条记录为如下形式之一:</p><ul><li><code>1 x y t</code>:Gosha 在时刻 $t$ 被邀请去格子 $(x,y)$。保证在当前时刻 $(x,y)$ 是没有猫的。</li><li><code>2 x y z</code>:有一只猫会在时刻 $t$ 来到格子 $(x,y)$。保证在当前时刻 $(x,y)$ 是没有别的猫的。</li><li><code>3 x y z</code>:有一只猫会在时刻 $t$ 离开格子 $(x,y)$。保证在当前时刻 $(x,y)$ 是有猫的。</li></ul><p>Gosha 需要你计算出对于每个邀请 $i$,他在时刻 $t_i$ 到达格子 $(x_i,y_i)$ 的方案数。假设他在时刻 $1$ 时从格子 $(1,1)$ 开始移动。</p><p>注意:Gosha 在移动过程中,可以多次访问同一个点,包括 $(1,1)$ 和 $(x_i,y_i)$。由于方案数过大,请将它对 $10^9+7$ 取模。</p><p>数据范围:$1\le n\cdot m\le 20$,$1\le q\le 10^4$,$1\le x_i\le n$,$1\le y_i\le m$,$2\le t_i<t_{i+1}\le 10^9$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>我们把这个 $n\times m$ 的矩阵压缩成一维的,定义 $f_i$ 表示走到 $i$ 格子的方案数。对于当前情况构造转移矩阵 $A$。$A_{i,j}$ 的值为 $1$ 当且仅当可以从 $i$ 走到 $j$。由于时间 $t_i$ 是递增的,直接<strong>矩阵快速幂</strong>求出答案即可。</p><p>注意:当某个点的状态改变(操作 $2$ 或 $3$)时,应该把它的 $f$ 值设为 $0$!</p><p><strong>时间复杂度</strong>:$O(nmq+(nm)^3\log t_i)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><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">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"><algorithm></span></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">25</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod=<span class="number">1e9</span>+<span class="number">7</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> dx[]={<span class="number">1</span>,<span class="number">-1</span>,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>},dy[]={<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">-1</span>,<span class="number">0</span>};</span><br><span class="line"><span class="keyword">int</span> h,w,n,q;</span><br><span class="line"><span class="keyword">bool</span> ok[N][N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">upd</span><span class="params">(<span class="keyword">int</span> &x,<span class="keyword">int</span> y)</span> </span>{</span><br><span class="line"> (x+=y)>=mod&&(x-=mod);</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Matrix</span> {</span></span><br><span class="line"> <span class="keyword">int</span> n,m,A[N][N];</span><br><span class="line"> Matrix(<span class="keyword">int</span> _n=<span class="number">0</span>,<span class="keyword">int</span> _m=<span class="number">0</span>) {</span><br><span class="line"> n=_n,m=_m,<span class="built_in">memset</span>(A,<span class="number">0</span>,<span class="keyword">sizeof</span>(A));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">void</span> <span class="keyword">operator</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) A[i][i]=<span class="number">1</span>;</span><br><span class="line"> }</span><br><span class="line"> Matrix <span class="keyword">operator</span> * (<span class="keyword">const</span> Matrix &b)<span class="keyword">const</span> {</span><br><span class="line"> <span class="function">Matrix <span class="title">ans</span><span class="params">(n,b.m)</span></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 class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=b.m;++j) <span class="keyword">for</span>(<span class="keyword">int</span> k=<span class="number">1</span>;k<=m;++k) {</span><br><span class="line"> upd(ans.A[i][j],<span class="number">1L</span>L*A[i][k]*b.A[k][j]%mod);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line"> Matrix <span class="keyword">operator</span> ^ (<span class="keyword">const</span> <span class="keyword">int</span> &b)<span class="keyword">const</span> {</span><br><span class="line"> Matrix ans(n,n),x=*this; ~ans;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> p=b;p;p>>=<span class="number">1</span>,x=x*x) <span class="keyword">if</span>(p&<span class="number">1</span>) ans=ans*x;</span><br><span class="line"> <span class="keyword">return</span> ans;</span><br><span class="line"> }</span><br><span class="line">};</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">build</span><span class="params">(Matrix &a)</span> </span>{</span><br><span class="line"> <span class="built_in">memset</span>(a.A,<span class="number">0</span>,<span class="keyword">sizeof</span>(a.A));</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=h;++i) <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=w;++j) <span class="keyword">if</span>(ok[i][j]) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=<span class="number">0</span>;k<=<span class="number">4</span>;++k) {</span><br><span class="line"> <span class="keyword">int</span> x=i+dx[k],y=j+dy[k];</span><br><span class="line"> <span class="keyword">if</span>(x>=<span class="number">1</span>&&x<=h&&y>=<span class="number">1</span>&&y<=w&&ok[x][y]) a.A[(i<span class="number">-1</span>)*w+j][(x<span class="number">-1</span>)*w+y]=<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="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">"%d%d%d"</span>,&h,&w,&q),n=h*w;</span><br><span class="line"> <span class="keyword">int</span> now=<span class="number">1</span>;</span><br><span class="line"> Matrix ans(n,1),a(n,n);</span><br><span class="line"> ans.A[<span class="number">1</span>][<span class="number">1</span>]=<span class="number">1</span>;</span><br><span class="line"> <span class="built_in">memset</span>(ok,<span class="number">1</span>,<span class="keyword">sizeof</span>(ok));</span><br><span class="line"> <span class="keyword">while</span>(q--) {</span><br><span class="line"> <span class="keyword">int</span> opt,x,y,t;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d%d"</span>,&opt,&x,&y,&t);</span><br><span class="line"> build(a),ans=(a^(t-now))*ans,now=t;</span><br><span class="line"> <span class="keyword">if</span>(opt==<span class="number">1</span>) <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,ans.A[(x<span class="number">-1</span>)*w+y][<span class="number">1</span>]);</span><br><span class="line"> <span class="keyword">if</span>(opt==<span class="number">2</span>) ans.A[(x<span class="number">-1</span>)*w+y][<span class="number">1</span>]=<span class="number">0</span>,ok[x][y]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">if</span>(opt==<span class="number">3</span>) ans.A[(x<span class="number">-1</span>)*w+y][<span class="number">1</span>]=<span class="number">0</span>,ok[x][y]=<span class="number">1</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></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/593/problem/E" target="_blank" rel="noopener">Codeforces 593E</a></p>
</blockquote>
<p>Gosha 的宇宙是一个由 $n$ 行 $m$ 列组成的表格。他经常被邀请去某个地方,每次接到邀请后,他会先计算到达那个地方的路径方案数,然后再动身出发。Gosha 的房子位于 $(1,1)$。</p>
<p>在任何时刻,Gosha 都会从当前格子到达相邻的格子,当然不会超出边界。此外,他也可以选择不移动而停留在当前格子里。</p>
<p>他除了喜欢奇怪的计算,还对猫过敏,因此他从来不去有猫的格子。Gosha 清楚地知道他何时何地会被邀请,也知道猫的在格子上的行程。形式化地讲,他有 $q$ 条记录,第 $i$ 条记录为如下形式之一:</p>
<ul>
<li><code>1 x y t</code>:Gosha 在时刻 $t$ 被邀请去格子 $(x,y)$。保证在当前时刻 $(x,y)$ 是没有猫的。</li>
<li><code>2 x y z</code>:有一只猫会在时刻 $t$ 来到格子 $(x,y)$。保证在当前时刻 $(x,y)$ 是没有别的猫的。</li>
<li><code>3 x y z</code>:有一只猫会在时刻 $t$ 离开格子 $(x,y)$。保证在当前时刻 $(x,y)$ 是有猫的。</li>
</ul>
<p>Gosha 需要你计算出对于每个邀请 $i$,他在时刻 $t_i$ 到达格子 $(x_i,y_i)$ 的方案数。假设他在时刻 $1$ 时从格子 $(1,1)$ 开始移动。</p>
<p>注意:Gosha 在移动过程中,可以多次访问同一个点,包括 $(1,1)$ 和 $(x_i,y_i)$。由于方案数过大,请将它对 $10^9+7$ 取模。</p>
<p>数据范围:$1\le n\cdot m\le 20$,$1\le q\le 10^4$,$1\le x_i\le n$,$1\le y_i\le m$,$2\le t_i&lt;t_{i+1}\le 10^9$</p>
</summary>
<category term="动态规划" scheme="http://hydingsy.github.io/tags/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="矩阵快速幂" scheme="http://hydingsy.github.io/tags/%E7%9F%A9%E9%98%B5%E5%BF%AB%E9%80%9F%E5%B9%82/"/>
</entry>
<entry>
<title>「Codeforces 1131F」Asya and Kittens</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-1131F-Asya-and-Kittens/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-1131F-Asya-and-Kittens/</id>
<published>2019-02-23T16:00:00.000Z</published>
<updated>2019-03-03T02:41:45.411Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/1131/problem/F" target="_blank" rel="noopener">Codeforces 1131F</a></p></blockquote><p>Asya 最近买了 $n$ 只小猫,把它们标号为 $1$ 到 $n$ 并放在笼子里。笼子由一行 $n$ 个格子组成,从左到右标号为 $1$ 到 $n$。相邻的格子之间透明的隔板,所以起初有 $n-1$ 个隔板。最初每个格子里只有一个只小猫。</p><p>经过观察,Asya 注意到相邻格子中的小猫想要一起玩。因此 Asya 开始删除相邻格子隔板。具体来说,在第 $i$ 天:</p><ul><li>注意到相邻的小猫 $x_i$ 和 $y_i$ 想到一起玩。</li><li>将这两个格子之间的隔板移除,创建了一个新的格子,原来两个格子里的小猫都到这个新的格子里。</li></ul><p>Asya 不会把隔板重新放回去,因此 $n-1$ 天后笼子里只有一个格子,所有的小猫都在里面。</p><p>每一天,Asya 都记得有哪一对小猫 $x_i,y_i$ 想到一起玩,但是她不记得一开始是怎么把小猫放到笼子里的。请帮助她找到小猫在 $n$ 个格子里的可能初始排列。数据保证有解,输出任意一个合法解即可。</p><p>数据范围:$2\le n\le 1.5\times 10^5$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>对于新建一个格子,我们将其看做是<strong>新建了一个点</strong>,这个点的左右儿子为<strong>原来的两个点</strong>(这两个点可能不是叶子,可能是之前合并得到的)。</p><p>这样我们得到了一棵<strong>二叉树</strong>。我们令最后一个点为根进行前序遍历,叶子节点在这个遍历中的序列就是答案。</p><p><strong>时间复杂度</strong>:$O(n\cdot\alpha(n))$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></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><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N=<span class="number">3e5</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> n,fa[N],ls[N],rs[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">find</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> fa[x]==x?x:fa[x]=find(fa[x]);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(x<=n) <span class="built_in">printf</span>(<span class="string">"%d "</span>,x);</span><br><span class="line"> <span class="keyword">else</span> dfs(ls[x]),dfs(rs[x]);</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">"%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+n;++i) fa[i]=i;</span><br><span class="line"> <span class="keyword">int</span> m=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="keyword">int</span> x,y;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&x,&y);</span><br><span class="line"> x=find(x),y=find(y);</span><br><span class="line"> ls[++m]=x,rs[m]=y;</span><br><span class="line"> fa[x]=fa[y]=m;</span><br><span class="line"> }</span><br><span class="line"> dfs(m);</span><br><span class="line"> <span class="built_in">puts</span>(<span class="string">""</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/1131/problem/F" target="_blank" rel="noopener">Codeforces 1131F</a></p>
</blockquote>
<p>Asya 最近买了 $n$ 只小猫,把它们标号为 $1$ 到 $n$ 并放在笼子里。笼子由一行 $n$ 个格子组成,从左到右标号为 $1$ 到 $n$。相邻的格子之间透明的隔板,所以起初有 $n-1$ 个隔板。最初每个格子里只有一个只小猫。</p>
<p>经过观察,Asya 注意到相邻格子中的小猫想要一起玩。因此 Asya 开始删除相邻格子隔板。具体来说,在第 $i$ 天:</p>
<ul>
<li>注意到相邻的小猫 $x_i$ 和 $y_i$ 想到一起玩。</li>
<li>将这两个格子之间的隔板移除,创建了一个新的格子,原来两个格子里的小猫都到这个新的格子里。</li>
</ul>
<p>Asya 不会把隔板重新放回去,因此 $n-1$ 天后笼子里只有一个格子,所有的小猫都在里面。</p>
<p>每一天,Asya 都记得有哪一对小猫 $x_i,y_i$ 想到一起玩,但是她不记得一开始是怎么把小猫放到笼子里的。请帮助她找到小猫在 $n$ 个格子里的可能初始排列。数据保证有解,输出任意一个合法解即可。</p>
<p>数据范围:$2\le n\le 1.5\times 10^5$</p>
</summary>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="并查集" scheme="http://hydingsy.github.io/tags/%E5%B9%B6%E6%9F%A5%E9%9B%86/"/>
</entry>
<entry>
<title>「Luogu 5171」Earthquake</title>
<link href="http://hydingsy.github.io/articles/problem-Luogu-5171-Earthquake/"/>
<id>http://hydingsy.github.io/articles/problem-Luogu-5171-Earthquake/</id>
<published>2019-02-23T16:00:00.000Z</published>
<updated>2019-03-01T06:54:42.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://www.luogu.org/problemnew/show/P5171" target="_blank" rel="noopener">Luogu 5171</a></p></blockquote><p>给定 $a,b,c$,求满足方程 $ax+by\le c$ 的非负整数解个数。</p><p>数据范围:$1\le a,b\le 10^9$,$0\le c\le \min(a,b)\times 10^9$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>通过<del>简单的</del><strong>线性规划</strong>知识,我们可以得到方程组:</p><script type="math/tex; mode=display">\begin{cases}x\ge 0 \\y\ge 0 \\ax+by\le c\end{cases}</script><p>分析可以得到答案为直线 $ax+by=c$(斜率显然是负数)与 $x$ 轴、$y$ 轴围成的图形中的整点数(包括边界)。也就是答案为(前一部分为 $x$ 轴上的点的个数):</p><script type="math/tex; mode=display">\left\lfloor\frac{c}{a}\right\rfloor+1+\sum_{i=0}^{\left\lfloor\frac{c}{a}\right\rfloor} \left\lfloor\frac{-ai+c}{b}\right\rfloor</script><p>是不是很像<strong>类欧几里德算法</strong>?具体推导过程详见:<a href="https://orzsiyuan.com/articles/algorithm-Similar-Euclidean-Algorithm/" target="_blank" rel="noopener">「算法笔记」类欧几里德算法</a></p><p>但是这样 $\sum$ 里是会有<strong>负数</strong>的。不信你按照类欧的公式推一下?$f(a,b,c,n)$ 是会递归到 $f\left(c,c-b-1,a,\left\lfloor\frac{an+b}{c}\right\rfloor-1\right)$ 的,这样递归之后直线在 $y$ 轴的截距就是负数了(如果是负数还要和 $0$ 取 $\max$……)。</p><p>我们把这个函数变成增函数。把 $x=0$ 和 $x=\left\lfloor\frac{c}{a}\right\rfloor$ 时函数上的两点对换,得到函数 $y=\frac{ax+c\bmod a}{b}$,故原式化为:</p><script type="math/tex; mode=display">\left\lfloor\frac{c}{a}\right\rfloor+1+\sum_{i=0}^{\left\lfloor\frac{c}{a}\right\rfloor} \left\lfloor\frac{ai+c\bmod a}{b}\right\rfloor</script><p>后半部分就是类欧几里德算法中的函数:</p><script type="math/tex; mode=display">f(a,c\bmod a,b,\left\lfloor\frac{c}{a}\right\rfloor)</script><p>时间复杂度:$O(\log a)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><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="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="function">LL <span class="title">F</span><span class="params">(LL a,LL b,LL c,LL n)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(a==<span class="number">0</span>) <span class="keyword">return</span> b/c*(n+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">if</span>(a>=c||b>=c) <span class="keyword">return</span> a/c*n*(n+<span class="number">1</span>)/<span class="number">2</span>+b/c*(n+<span class="number">1</span>)+F(a%c,b%c,c,n);</span><br><span class="line"> LL m=(a*n+b)/c;</span><br><span class="line"> <span class="keyword">return</span> n*m-F(c,c-b<span class="number">-1</span>,a,m<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">main</span><span class="params">()</span> </span>{</span><br><span class="line"> LL a,b,c;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld%lld%lld"</span>,&a,&b,&c);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,F(a,c%a,b,c/a)+c/a+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://www.luogu.org/problemnew/show/P5171" target="_blank" rel="noopener">Luogu 5171</a></p>
</blockquote>
<p>给定 $a,b,c$,求满足方程 $ax+by\le c$ 的非负整数解个数。</p>
<p>数据范围:$1\le a,b\le 10^9$,$0\le c\le \min(a,b)\times 10^9$</p>
</summary>
<category term="类欧几里德算法" scheme="http://hydingsy.github.io/tags/%E7%B1%BB%E6%AC%A7%E5%87%A0%E9%87%8C%E5%BE%B7%E7%AE%97%E6%B3%95/"/>
<category term="Luogu" scheme="http://hydingsy.github.io/tags/Luogu/"/>
<category term="线性规划" scheme="http://hydingsy.github.io/tags/%E7%BA%BF%E6%80%A7%E8%A7%84%E5%88%92/"/>
</entry>
<entry>
<title>「Codeforces 788B」Weird Journey</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-788B-Weird-Journey/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-788B-Weird-Journey/</id>
<published>2019-02-22T16:00:00.000Z</published>
<updated>2019-02-28T08:28:22.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/788/problem/B" target="_blank" rel="noopener">Codeforces 788B</a></p></blockquote><p>众所周知,Uzhlyandia 有 $n$ 个城市由 $m$ 条道路相连(保证没有重边,但是可能有自环)。定义一条路径是好的,当且仅当这条路径经过 $m-2$ 条边恰好 $2$ 次,另外 $2$ 条边经过恰好 $1$ 次。路径的起始城市和结束城市可以是任意的。</p><p>现在请你计算出有多少条路径是好的,两条路径是不同的当且仅当有一条边不同。</p><p>数据范围:$1\le n,m\le 10^6$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>路径经过 $2$ 次很难处理,我们把每条路径<strong>复制一遍</strong>,这样一来得到:其中 $2$ 条边不经过,其余边恰好经过 $1$ 次。</p><p>换言之,我们把这张新图上的 $2$ 条边删去,这张图存在<strong>欧拉路径</strong>(不多于 $2$ 个点的度数为奇数)。</p><p>新图中,显然每个点的度数都是<strong>偶数</strong>了,我们那么有如下 $3$ 种删边方法:</p><ul><li>删去两个自环(这个点的度数 $-4$)。</li><li>删去一个自环和任意一条普通的边(一个点的度数 $-2$,另外两个点度数各 $-1$)。</li><li>删去两条有共同端点的边(一个点度数 $-2$,另外两个点度数各 $-1$)。</li></ul><p>统计自环个数、边数、度数即可得到答案。</p><p>最后注意一下无解情况!不一定是图不连通,比如 $\text{Codeforces}$ 上的这组数据(应该是有解的):</p><figure class="highlight basic"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="symbol">4 </span><span class="number">4</span></span><br><span class="line"><span class="symbol">2 </span><span class="number">3</span></span><br><span class="line"><span class="symbol">2 </span><span class="number">4</span></span><br><span class="line"><span class="symbol">3 </span><span class="number">4</span></span><br><span class="line"><span class="symbol">4 </span><span class="number">4</span></span><br></pre></td></tr></table></figure><p>因此无解当且仅当有连边的点之间相互连通。</p><p><strong>时间复杂度</strong>:$O(m+n\cdot\alpha(n))$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><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">include</span> <span class="meta-string"><algorithm></span></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">1e6</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> n,m,deg[N],fa[N];</span><br><span class="line"><span class="keyword">bool</span> vis[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">find</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> fa[x]==x?x:fa[x]=find(fa[x]);</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">"%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<=n;++i) fa[i]=i;</span><br><span class="line"> <span class="keyword">int</span> cnt=<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<=m;++i) {</span><br><span class="line"> <span class="keyword">int</span> u,v;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&u,&v);</span><br><span class="line"> vis[u]=vis[v]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(u==v) ++cnt;</span><br><span class="line"> <span class="keyword">else</span> ++deg[u],++deg[v];</span><br><span class="line"> fa[find(u)]=find(v);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> rt=<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 class="keyword">if</span>(vis[i]) {rt=i;<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<=n;++i) <span class="keyword">if</span>(vis[i]&&find(i)!=find(rt)) <span class="keyword">return</span> <span class="built_in">puts</span>(<span class="string">"0"</span>),<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> ans=<span class="number">0</span>;</span><br><span class="line"> ans+=<span class="number">1L</span>L*cnt*(m-cnt);</span><br><span class="line"> ans+=<span class="number">1L</span>L*cnt*(cnt<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=<span class="number">1</span>;i<=n;++i) ans+=<span class="number">1L</span>L*deg[i]*(deg[i]<span class="number">-1</span>)/<span class="number">2</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,ans);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/788/problem/B" target="_blank" rel="noopener">Codeforces 788B</a></p>
</blockquote>
<p>众所周知,Uzhlyandia 有 $n$ 个城市由 $m$ 条道路相连(保证没有重边,但是可能有自环)。定义一条路径是好的,当且仅当这条路径经过 $m-2$ 条边恰好 $2$ 次,另外 $2$ 条边经过恰好 $1$ 次。路径的起始城市和结束城市可以是任意的。</p>
<p>现在请你计算出有多少条路径是好的,两条路径是不同的当且仅当有一条边不同。</p>
<p>数据范围:$1\le n,m\le 10^6$</p>
</summary>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="思维" scheme="http://hydingsy.github.io/tags/%E6%80%9D%E7%BB%B4/"/>
<category term="欧拉路径" scheme="http://hydingsy.github.io/tags/%E6%AC%A7%E6%8B%89%E8%B7%AF%E5%BE%84/"/>
</entry>
<entry>
<title>「IOI 2011」Race</title>
<link href="http://hydingsy.github.io/articles/problem-IOI-2011-Race/"/>
<id>http://hydingsy.github.io/articles/problem-IOI-2011-Race/</id>
<published>2019-02-21T16:00:00.000Z</published>
<updated>2019-03-01T05:03:14.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://www.luogu.org/problemnew/show/P4149" target="_blank" rel="noopener">Luogu 4149</a></p></blockquote><p>给一棵有 $n$ 个节点的树,每条边有权。求一条简单路径,权值和等于 $k$,且边的数量最小。无解输出 $-1$。</p><p>数据范围:$1\le n\le 2\times 10^5$,$1\le k\le 10^6$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p><del>IOI 点分治入门题</del></p><p>为了方便计数,我们采用分别处理每棵子树的方法,而不是容斥(容斥无限 $\text{WA}$ 根本调不出来 QAQ)。</p><p>记录 $f_i$ 表示长度为 $i$ 的链包含的最小边数,对于长度大于 $k$ 的链可以直接忽略。</p><p><strong>时间复杂度</strong>:$O(n\log n)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><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">include</span> <span class="meta-string"><algorithm></span></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">2e5</span>+<span class="number">5</span>,M=<span class="number">4e5</span>+<span class="number">5</span>,K=<span class="number">1e6</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> INF=<span class="number">1</span><<<span class="number">30</span>;</span><br><span class="line"><span class="keyword">int</span> n,k,tot,tp,root,sum,lnk[N],ter[M],nxt[M],val[M],mx[N],sz[N],q[N],f[K],ans;</span><br><span class="line"><span class="keyword">bool</span> vis[N];</span><br><span class="line"><span class="built_in">std</span>::pair<<span class="keyword">int</span>,<span class="keyword">int</span>> s[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> v,<span class="keyword">int</span> w)</span> </span>{</span><br><span class="line"> ter[++tot]=v,nxt[tot]=lnk[u],lnk[u]=tot,val[tot]=w;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">getRoot</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> fa)</span> </span>{</span><br><span class="line"> sz[u]=<span class="number">1</span>,mx[u]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(v==fa||vis[v]) <span class="keyword">continue</span>;</span><br><span class="line"> getRoot(v,u);</span><br><span class="line"> sz[u]+=sz[v];</span><br><span class="line"> mx[u]=<span class="built_in">std</span>::max(mx[u],sz[v]);</span><br><span class="line"> }</span><br><span class="line"> mx[u]=<span class="built_in">std</span>::max(mx[u],sum-sz[u]);</span><br><span class="line"> <span class="keyword">if</span>(mx[root]>mx[u]) root=u;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">getDis</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> fa,<span class="keyword">int</span> d,<span class="keyword">int</span> p)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span>(d>k) <span class="keyword">return</span>;</span><br><span class="line"> s[++tp]=<span class="built_in">std</span>::make_pair(d,p);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(v==fa||vis[v]) <span class="keyword">continue</span>;</span><br><span class="line"> getDis(v,u,d+val[i],p+<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">void</span> <span class="title">solve</span><span class="params">(<span class="keyword">int</span> u)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> cnt=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(vis[v]) <span class="keyword">continue</span>;</span><br><span class="line"> tp=<span class="number">0</span>,getDis(v,u,val[i],<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<=tp;++i) ans=<span class="built_in">std</span>::min(ans,s[i].second+f[k-s[i].first]);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=tp;++i) f[q[++cnt]=s[i].first]=<span class="built_in">std</span>::min(f[s[i].first],s[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">1</span>;i<=cnt;++i) f[q[i]]=INF;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> u)</span> </span>{</span><br><span class="line"> vis[u]=<span class="number">1</span>,f[<span class="number">0</span>]=<span class="number">0</span>,solve(u);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(vis[v]) <span class="keyword">continue</span>;</span><br><span class="line"> root=<span class="number">0</span>,sum=sz[v],getRoot(v,u),dfs(root);</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">"%d%d"</span>,&n,&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="keyword">int</span> u,v,w;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>,&u,&v,&w),++u,++v;</span><br><span class="line"> add(u,v,w),add(v,u,w);</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<=k;++i) f[i]=INF;</span><br><span class="line"> ans=mx[<span class="number">0</span>]=INF;</span><br><span class="line"> root=<span class="number">0</span>,sum=n,getRoot(<span class="number">1</span>,<span class="number">0</span>),dfs(root);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,ans==INF?<span class="number">-1</span>:ans);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://www.luogu.org/problemnew/show/P4149" target="_blank" rel="noopener">Luogu 4149</a></p>
</blockquote>
<p>给一棵有 $n$ 个节点的树,每条边有权。求一条简单路径,权值和等于 $k$,且边的数量最小。无解输出 $-1$。</p>
<p>数据范围:$1\le n\le 2\times 10^5$,$1\le k\le 10^6$</p>
</summary>
<category term="Luogu" scheme="http://hydingsy.github.io/tags/Luogu/"/>
<category term="IOI" scheme="http://hydingsy.github.io/tags/IOI/"/>
<category term="点分治" scheme="http://hydingsy.github.io/tags/%E7%82%B9%E5%88%86%E6%B2%BB/"/>
</entry>
<entry>
<title>「Codeforces 980E」The Number Games</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-980E-The-Number-Games/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-980E-The-Number-Games/</id>
<published>2019-02-21T16:00:00.000Z</published>
<updated>2019-03-01T01:17:28.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/980/problem/E" target="_blank" rel="noopener">Codeforces 980E</a></p></blockquote><p>Panel 国将举办名为数字游戏的年度表演。每个省派出一名选手。</p><p>国家有 $n$ 个编号从 $1$ 到 $n$ 的省,每个省刚好有一条路径将其与其他省相连。第 $i$ 个省出来的代表有 $2^i$ 名粉丝。</p><p>今年,主席打算削减开支,他想要踢掉 $k$ 个选手。但是,被踢掉的选手的省将很生气,并且不会让别的任何人从这个省经过。</p><p>主席想确保所有剩下选手的省都互相可达,他也希望最大化参与表演的选手的粉丝数。</p><p>主席该踢掉哪些选手呢?</p><p>数据范围:$1\le k<n\le 10^6$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>显然这是一棵树,我们要踢掉的一定是当前度数为 $1$ 的点。换言之,保留的点一定是原树的一个<strong>连通块</strong>。</p><p>再观察 $2^i$ 的性质,我们发现保留一个点 $i$ 一定比保留所有的 $1,2,\dots,i-1$ 更优。那么肯定要尽量删除标号小的点。但是反例如下:</p><blockquote><p>$n=5$,$k=3$,这是一条链:$4-1-5-2-3$</p><p>如果直接删除标号小的,那么删除的点为 $3,2,4$。而最优解为删除 $4,1,3$。</p></blockquote><p>这种贪心过程由于没法考虑到非叶子节点的大小,因此是错误的。那么我们考虑一个反面:尽量<strong>保留标号大的节点</strong>。为了方便操作,我们以 $n$ 作为根节点(因为它一定是要保留的)。具体操作过程如下:</p><ol><li>从大到小遍历节点,假设当前节点为 $x$。我们把已经保留的点叫做<strong>标记点</strong>。</li><li>如果节点 $x$ 到根节点经过的标记点有 $m$ 个,那么如果要保留点 $x$,还需要额外保留它到根路径上的非标记点 $dep_x-m-1$ 个(其中 $dep$ 为深度,根的深度为 $1$),共需要保留 $dep_x-m$ 个。</li><li>如果 $dep_x-m$ 不大于当前允许保留的节点个数,那么把这些点全部保留;否则不操作。</li><li>跳到第 $1$ 步。</li></ol><p>最后考虑实现问题:</p><ul><li><p>如何维护标记点个数?</p><p>我们发现每加入一个标记点 $x$,$x$ 子树内的节点到根的标记点个数都会增加 $1$,直接求出 $\text{DFS}$ 序,用<strong>树状数组</strong>维护即可。</p></li><li><p>如何把 $dep_x-m$ 个点设为标记点。</p><p>暴力往上跳即可,跳到标记点就退出。每个点最多经过 $1$ 次,复杂度正确。</p></li></ul><p><strong>时间复杂度</strong>:$O(n\log n)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><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><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> N=<span class="number">1e6</span>+<span class="number">5</span>,M=<span class="number">2e6</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">int</span> n,k,tot,idx,lnk[N],ter[M],nxt[M],dfn[N],dep[N],fa[N],sz[N],b[N];</span><br><span class="line"><span class="keyword">bool</span> flg[N];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">add</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> v)</span> </span>{</span><br><span class="line"> ter[++tot]=v,nxt[tot]=lnk[u],lnk[u]=tot;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">dfs</span><span class="params">(<span class="keyword">int</span> u,<span class="keyword">int</span> p)</span> </span>{</span><br><span class="line"> dfn[u]=++idx,dep[u]=dep[fa[u]=p]+<span class="number">1</span>,sz[u]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=lnk[u];i;i=nxt[i]) {</span><br><span class="line"> <span class="keyword">int</span> v=ter[i];</span><br><span class="line"> <span class="keyword">if</span>(v==p) <span class="keyword">continue</span>;</span><br><span class="line"> dfs(v,u);</span><br><span class="line"> sz[u]+=sz[v];</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">modify</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> v)</span> </span>{</span><br><span class="line"> <span class="keyword">for</span>(;x<=n;x+=x&-x) b[x]+=v;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">query</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(;x;x^=x&-x) ans+=b[x];</span><br><span class="line"> <span class="keyword">return</span> ans;</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">"%d%d"</span>,&n,&k);</span><br><span class="line"> k=n-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="keyword">int</span> u,v;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&u,&v);</span><br><span class="line"> add(u,v),add(v,u);</span><br><span class="line"> }</span><br><span class="line"> dfs(n,<span class="number">0</span>);</span><br><span class="line"> flg[n]=<span class="number">1</span>,--k;</span><br><span class="line"> modify(dfn[n],<span class="number">1</span>),modify(dfn[n]+sz[n],<span class="number">-1</span>);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n<span class="number">-1</span>;i>=<span class="number">1</span>;--i) {</span><br><span class="line"> <span class="keyword">if</span>(!flg[i]&&dep[i]-query(dfn[i])<=k) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> x=i;x!=n&&!flg[x];x=fa[x]) {</span><br><span class="line"> modify(dfn[x],<span class="number">1</span>),modify(dfn[x]+sz[x],<span class="number">-1</span>);</span><br><span class="line"> flg[x]=<span class="number">1</span>,--k;</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 class="keyword">if</span>(!flg[i]) <span class="built_in">printf</span>(<span class="string">"%d "</span>,i);</span><br><span class="line"> <span class="built_in">puts</span>(<span class="string">""</span>);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/980/problem/E" target="_blank" rel="noopener">Codeforces 980E</a></p>
</blockquote>
<p>Panel 国将举办名为数字游戏的年度表演。每个省派出一名选手。</p>
<p>国家有 $n$ 个编号从 $1$ 到 $n$ 的省,每个省刚好有一条路径将其与其他省相连。第 $i$ 个省出来的代表有 $2^i$ 名粉丝。</p>
<p>今年,主席打算削减开支,他想要踢掉 $k$ 个选手。但是,被踢掉的选手的省将很生气,并且不会让别的任何人从这个省经过。</p>
<p>主席想确保所有剩下选手的省都互相可达,他也希望最大化参与表演的选手的粉丝数。</p>
<p>主席该踢掉哪些选手呢?</p>
<p>数据范围:$1\le k&lt;n\le 10^6$</p>
</summary>
<category term="数据结构" scheme="http://hydingsy.github.io/tags/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84/"/>
<category term="贪心" scheme="http://hydingsy.github.io/tags/%E8%B4%AA%E5%BF%83/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="树状数组" scheme="http://hydingsy.github.io/tags/%E6%A0%91%E7%8A%B6%E6%95%B0%E7%BB%84/"/>
<category term="DFS 序" scheme="http://hydingsy.github.io/tags/DFS-%E5%BA%8F/"/>
</entry>
<entry>
<title>「Codeforces 555B」Case of Fugitive</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-555B-Case-of-Fugitive/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-555B-Case-of-Fugitive/</id>
<published>2019-02-21T16:00:00.000Z</published>
<updated>2019-02-28T07:41:20.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/555/problem/B" target="_blank" rel="noopener">Codeforces 555B</a></p></blockquote><p>有 $n$ 个狭窄的岛屿排成一排的群岛,我们将他们表示为直线上不相交的线段:岛屿 $i$ 的坐标为 $[l_i,r_i]$。保证对于所有的 $1\le i\le n-1$,都有 $r_i<l_{i+1}$。</p><p>你需要在所有相邻的岛屿之间架上桥梁。一座长度为 $a$ 的桥可以架在第 $i$ 和 $i+1$ 个岛屿之间,当且仅当存在 $l_i\le x\le r_i$,$l_{i+1}\le y\le r_{i+1}$ 满足 $y-x=a$。</p><p>现在你有 $m$ 座桥梁,第 $i$ 座桥梁的长度为 $a_i$,并且每座桥梁最多只能使用一次。请问是否可以把任意两个相邻的岛屿连通。如果可行,输出 <code>Yes</code> 和方案;否则输出 <code>No</code>。</p><p>数据范围:$2\le n\le 2\times 10^5$,$1\le m\le 2\times 10^5$,$1\le l_i\le r_i\le 10^{18}$,$1\le a_i\le 10^{18}$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>我们先求出相邻两个岛屿之间能架的桥的长度区间,显然对于岛屿 $i,i+1$,长度区间为 $[l_{i+1}-r_i,r_{i+1}-l_i]$,记为 $[s_i,t_i]$。这就是说,我们要对每个 $i\in [1,n)$,配上一个 $a_j$ 满足 $s_i\le a_j\le t_i$。</p><p>考虑贪心策略:把所有的长度区间按照<strong>右端点</strong>为第一关键字,<strong>左端点</strong>为第二关键字,从小到大排序。对于第 $i$ 个区间,我们找到第一个不小于 $s_i$ 的 $a_j$ 与其配对。如果出现无解情况(找不到不小于 $s_i$ 的值,或者 $a_j>r_i$)就直接退出。这个过程可以通过 $\text{set}$ 实现。</p><p><strong>时间复杂度</strong>:$O(n\log nm)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><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">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><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">int</span> n,m,ans[N];</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Inter</span> {</span></span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> l,r;</span><br><span class="line"> <span class="keyword">int</span> id;</span><br><span class="line"> <span class="keyword">bool</span> <span class="keyword">operator</span> < (<span class="keyword">const</span> Inter &b)<span class="keyword">const</span> {</span><br><span class="line"> <span class="keyword">return</span> r==b.r?l<b.l:r<b.r;</span><br><span class="line"> }</span><br><span class="line">} a[N];</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Bridge</span> {</span></span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> x;</span><br><span class="line"> <span class="keyword">int</span> id;</span><br><span class="line"> <span class="keyword">bool</span> <span class="keyword">operator</span> < (<span class="keyword">const</span> Bridge &b)<span class="keyword">const</span> {</span><br><span class="line"> <span class="keyword">return</span> x<b.x;</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="built_in">scanf</span>(<span class="string">"%d%d"</span>,&n,&m);</span><br><span class="line"> <span class="keyword">long</span> <span class="keyword">long</span> lstL,lstR;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld%lld"</span>,&lstL,&lstR);</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">long</span> <span class="keyword">long</span> L,R;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld%lld"</span>,&L,&R);</span><br><span class="line"> a[i].l=L-lstR,a[i].r=R-lstL,a[i].id=i;</span><br><span class="line"> lstL=L,lstR=R;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">multiset</span><Bridge> s;</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="keyword">long</span> <span class="keyword">long</span> x;</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%lld"</span>,&x);</span><br><span class="line"> s.insert(Bridge{x,i});</span><br><span class="line"> }</span><br><span class="line"> --n;</span><br><span class="line"> <span class="built_in">std</span>::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"> <span class="keyword">long</span> <span class="keyword">long</span> l=a[i].l,r=a[i].r;</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">multiset</span><Bridge>::iterator it=s.lower_bound(Bridge{l,<span class="number">0</span>});</span><br><span class="line"> <span class="keyword">if</span>(it==s.end()||it->x>r) <span class="keyword">return</span> <span class="built_in">puts</span>(<span class="string">"No"</span>),<span class="number">0</span>;</span><br><span class="line"> ans[a[i].id]=it->id,s.erase(it);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">puts</span>(<span class="string">"Yes"</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 class="built_in">printf</span>(<span class="string">"%d%c"</span>,ans[i],<span class="string">" \n"</span>[i==n]);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/555/problem/B" target="_blank" rel="noopener">Codeforces 555B</a></p>
</blockquote>
<p>有 $n$ 个狭窄的岛屿排成一排的群岛,我们将他们表示为直线上不相交的线段:岛屿 $i$ 的坐标为 $[l_i,r_i]$。保证对于所有的 $1\le i\le n-1$,都有 $r_i&lt;l_{i+1}$。</p>
<p>你需要在所有相邻的岛屿之间架上桥梁。一座长度为 $a$ 的桥可以架在第 $i$ 和 $i+1$ 个岛屿之间,当且仅当存在 $l_i\le x\le r_i$,$l_{i+1}\le y\le r_{i+1}$ 满足 $y-x=a$。</p>
<p>现在你有 $m$ 座桥梁,第 $i$ 座桥梁的长度为 $a_i$,并且每座桥梁最多只能使用一次。请问是否可以把任意两个相邻的岛屿连通。如果可行,输出 <code>Yes</code> 和方案;否则输出 <code>No</code>。</p>
<p>数据范围:$2\le n\le 2\times 10^5$,$1\le m\le 2\times 10^5$,$1\le l_i\le r_i\le 10^{18}$,$1\le a_i\le 10^{18}$</p>
</summary>
<category term="贪心" scheme="http://hydingsy.github.io/tags/%E8%B4%AA%E5%BF%83/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
</entry>
<entry>
<title>「Codeforces 1063C」Dwarves, Hats and Extrasensory Abilities</title>
<link href="http://hydingsy.github.io/articles/problem-Codeforces-1063C-Dwarves-Hats-and-Extrasensory-Abilities/"/>
<id>http://hydingsy.github.io/articles/problem-Codeforces-1063C-Dwarves-Hats-and-Extrasensory-Abilities/</id>
<published>2019-02-20T16:00:00.000Z</published>
<updated>2019-02-28T03:23:40.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://codeforces.com/contest/1063/problem/C" target="_blank" rel="noopener">Codeforces 1063C</a></p></blockquote><p>这是一道交互题。</p><p>给你一个正整数 $n$ 表示有 $n$ 个点。接下来你可以询问任意 $n$ 个点 $(x,y)$ 满足 $0\le x,y\le 10^9$,交互器会告诉你每个点的颜色是黑色还是白色。你需要确定一条直线,使得直线将所有的点分成两个部分,一部分的点都是白色,另一部分都是黑色。</p><p>数据范围:$1\le n\le 30$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>由于是任意询问点,我们可以使所有的点<strong>都在一条直线上</strong>,左侧、右侧的点颜色不同。</p><p>首先询问点 $(0,y)$(这里的 $y$ 可以随意确定,只不过是保证点连成的直线和 $x$ 轴平行罢了),假设得到的颜色为白色,那么我们通过某种构造方法,使得左侧的点都是白色,右侧都是黑色。注意:接下来的分析都依次为根据!</p><p>定义搜索区间为<strong>最右侧的白点</strong>到<strong>最左侧的黑点</strong>形成的区间(不包含两端)$[l,r]$。每次询问区间中点 $mid$,如果 $(mid,y)$ 的颜色为白色,那么搜索区间变为 $(mid,r]$ 否则为 $[l,mid)$。</p><p>这样我们最多可以询问 $\left\lfloor\log_2 10^9\right\rfloor=30$ 个点,刚好达到 $n$ 的上限。</p><p>画图可知,通过 $(l,0)$ 和 $(r,2)$ 的直线是满足要求的。(千万不要使用 $x=\left\lfloor\frac{l+r}{2}\right\rfloor$ 这条直线,在 $r-l\le 1$ 时会出错!)</p><p><strong>时间复杂度</strong>:$O(n)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></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><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">ask</span><span class="params">(<span class="keyword">int</span> x)</span> </span>{</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d 1\n"</span>,x),fflush(<span class="built_in">stdout</span>);</span><br><span class="line"> <span class="keyword">char</span> s[<span class="number">10</span>];</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>,s+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">return</span> s[<span class="number">1</span>]==<span class="string">'w'</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> 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">int</span> col=ask(<span class="number">0</span>);</span><br><span class="line"> <span class="keyword">int</span> l=<span class="number">1</span>,r=<span class="number">1e9</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 class="keyword">int</span> mid=(l+r)>><span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(ask(mid)==col) 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">"%d 0 %d 2\n"</span>,l,r);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://codeforces.com/contest/1063/problem/C" target="_blank" rel="noopener">Codeforces 1063C</a></p>
</blockquote>
<p>这是一道交互题。</p>
<p>给你一个正整数 $n$ 表示有 $n$ 个点。接下来你可以询问任意 $n$ 个点 $(x,y)$ 满足 $0\le x,y\le 10^9$,交互器会告诉你每个点的颜色是黑色还是白色。你需要确定一条直线,使得直线将所有的点分成两个部分,一部分的点都是白色,另一部分都是黑色。</p>
<p>数据范围:$1\le n\le 30$</p>
</summary>
<category term="交互题" scheme="http://hydingsy.github.io/tags/%E4%BA%A4%E4%BA%92%E9%A2%98/"/>
<category term="Codeforces" scheme="http://hydingsy.github.io/tags/Codeforces/"/>
<category term="二分" scheme="http://hydingsy.github.io/tags/%E4%BA%8C%E5%88%86/"/>
</entry>
<entry>
<title>「Luogu 5196」Cow Poetry</title>
<link href="http://hydingsy.github.io/articles/problem-Luogu-5196-Cow-Poetry/"/>
<id>http://hydingsy.github.io/articles/problem-Luogu-5196-Cow-Poetry/</id>
<published>2019-02-16T16:00:00.000Z</published>
<updated>2019-02-27T06:12:24.000Z</updated>
<content type="html"><![CDATA[<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote><p>题目链接:<a href="https://www.luogu.org/problemnew/show/P5196" target="_blank" rel="noopener">Luogu 5196</a></p></blockquote><p>不为 Farmer John 所知的是,Bessie 还热衷于资助艺术创作!最近,她开始研究许多伟大的诗人们,而现在,她想要尝试创作一些属于自己的诗歌了。Bessie 认识 $n$ 个单词,她想要将她们写进她的诗。Bessie 已经计算了她认识的每个单词的长度 $s_i$,以音节为单位,并且她将这些单词划分成了不同的“韵部”,第 $i$ 个单词的韵部为 $c_i$。每个单词仅与属于同一韵部的其他单词押韵。</p><p>Bessie 的每首诗由 $m$ 行组成,每一行必须由 $k$ 个音节构成。此外,Bessie 的诗必须遵循某个指定的押韵模式。每行有一个押韵模式,用大写字母 $e_i$ 表示。所有押韵模式等于 $e_i$ 的行必须以同一韵部的单词结尾。不同 $e_i$ 值的行并非必须以不同的韵部的单词结尾。</p><p>Bessie 想要知道她可以写出多少首符合限制条件的不同的诗,答案对 $10^9+7$ 取模。</p><p>数据范围:$1\le n,k\le 5\times 10^3$,$1\le m\le 10^5$,$1\le s_i\le k$,$1\le c_i\le n$</p><a id="more"></a><hr><h2 id="Solution"><a href="#Solution" class="headerlink" title="Solution"></a>Solution</h2><p>很显然是一个 $\text{DP}$ 计数题。定义状态 $f(i,j)$ 表示长度为 $i$ 的句子,以 $j$ 韵部结尾的方案数。</p><p>我们枚举当前长度 $i$,以韵部 $j$ 结尾,上一个单词的韵部 $k$,那么有转移:</p><script type="math/tex; mode=display">f(i,j)=\sum_{x=1,c_x=j}^n\sum_{k=1}^n f(i-s_x,k)</script><p>略作优化后写成伪代码就是:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=k;++i) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) {</span><br><span class="line"> <span class="keyword">if</span>(i<s[j]) <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=<span class="number">1</span>;k<=n;++k) {</span><br><span class="line"> f[i][c[j]]+=f[i-s[j]][k];</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>很显然这个转移是 $O(n^2k)$ 的,无法接受。</p><p>我们发现最外面的 $i$ 和 $j$ 的枚举是没法去掉了,试图把内层的 $k$ 的循环优化掉。设 $g(i)$ 表示长度为 $i$ 的总方案数:</p><script type="math/tex; mode=display">g(i)=\sum_{k=1}^n f(i,k)</script><p>那么我们的转移就是:</p><script type="math/tex; mode=display">f(i,j)=\sum_{x=1,c_x=j}^n g(i-s_x)</script><p>最后考虑句子的统计。记韵部为 $i$ 的句子有 $cnt_i$ 个,那么答案就是:</p><script type="math/tex; mode=display">\prod_{i=1}^{26}\sum_{j=1}^n f(k,j)^{cnt_i}</script><p><strong>时间复杂度</strong>:$O(nk)$</p><hr><h2 id="Code"><a href="#Code" class="headerlink" title="Code"></a>Code</h2><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><cstdio></span></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">5e3</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> mod=<span class="number">1e9</span>+<span class="number">7</span>;</span><br><span class="line"><span class="keyword">int</span> n,m,k,l[N],c[N],f[N][N],g[N],cnt[<span class="number">26</span>];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">upd</span><span class="params">(<span class="keyword">int</span> &x,<span class="keyword">int</span> y)</span> </span>{</span><br><span class="line"> (x+=y)>=mod&&(x-=mod);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">char</span> <span class="title">getc</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="keyword">char</span> c=getchar();</span><br><span class="line"> <span class="keyword">while</span>(c<<span class="string">'A'</span>||c><span class="string">'Z'</span>) c=getchar();</span><br><span class="line"> <span class="keyword">return</span> c;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">pow</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> p)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> ans=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(;p;p>>=<span class="number">1</span>,x=<span class="number">1L</span>L*x*x%mod) <span class="keyword">if</span>(p&<span class="number">1</span>) ans=<span class="number">1L</span>L*ans*x%mod;</span><br><span class="line"> <span class="keyword">return</span> ans;</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">"%d%d%d"</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 class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&l[i],&c[i]);</span><br><span class="line"> g[<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<=k;++i) {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) <span class="keyword">if</span>(i>=l[j]) upd(f[i][c[j]],g[i-l[j]]);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) upd(g[i],f[i][j]);</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) ++cnt[getc()-<span class="string">'A'</span>];</span><br><span class="line"> <span class="keyword">int</span> ans=<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<<span class="number">26</span>;++i) <span class="keyword">if</span>(cnt[i]) {</span><br><span class="line"> <span class="keyword">int</span> sum=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n;++j) upd(sum,<span class="built_in">pow</span>(f[k][j],cnt[i]));</span><br><span class="line"> ans=<span class="number">1L</span>L*ans*sum%mod;</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,ans);</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h2 id="Description"><a href="#Description" class="headerlink" title="Description"></a>Description</h2><blockquote>
<p>题目链接:<a href="https://www.luogu.org/problemnew/show/P5196" target="_blank" rel="noopener">Luogu 5196</a></p>
</blockquote>
<p>不为 Farmer John 所知的是,Bessie 还热衷于资助艺术创作!最近,她开始研究许多伟大的诗人们,而现在,她想要尝试创作一些属于自己的诗歌了。Bessie 认识 $n$ 个单词,她想要将她们写进她的诗。Bessie 已经计算了她认识的每个单词的长度 $s_i$,以音节为单位,并且她将这些单词划分成了不同的“韵部”,第 $i$ 个单词的韵部为 $c_i$。每个单词仅与属于同一韵部的其他单词押韵。</p>
<p>Bessie 的每首诗由 $m$ 行组成,每一行必须由 $k$ 个音节构成。此外,Bessie 的诗必须遵循某个指定的押韵模式。每行有一个押韵模式,用大写字母 $e_i$ 表示。所有押韵模式等于 $e_i$ 的行必须以同一韵部的单词结尾。不同 $e_i$ 值的行并非必须以不同的韵部的单词结尾。</p>
<p>Bessie 想要知道她可以写出多少首符合限制条件的不同的诗,答案对 $10^9+7$ 取模。</p>
<p>数据范围:$1\le n,k\le 5\times 10^3$,$1\le m\le 10^5$,$1\le s_i\le k$,$1\le c_i\le n$</p>
</summary>
<category term="动态规划" scheme="http://hydingsy.github.io/tags/%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92/"/>
<category term="Luogu" scheme="http://hydingsy.github.io/tags/Luogu/"/>
<category term="背包" scheme="http://hydingsy.github.io/tags/%E8%83%8C%E5%8C%85/"/>
</entry>
</feed>