-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
622 lines (351 loc) · 212 KB
/
search.xml
File metadata and controls
622 lines (351 loc) · 212 KB
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>new-blog</title>
<link href="/2021/03/07/new-blog/"/>
<url>/2021/03/07/new-blog/</url>
<content type="html"><![CDATA[<p>这个博客以后就不更了~</p><p>欢迎来新的博客玩~</p><p><a href="https://kamome.moe" target="_blank" rel="noopener">https://kamome.moe</a></p>]]></content>
<categories>
<category> Others </category>
</categories>
<tags>
<tag> Others </tag>
</tags>
</entry>
<entry>
<title>HNOI2019 白兔之舞</title>
<link href="/2019/07/09/HNOI2019%E7%99%BD%E5%85%94%E4%B9%8B%E8%88%9E/"/>
<url>/2019/07/09/HNOI2019%E7%99%BD%E5%85%94%E4%B9%8B%E8%88%9E/</url>
<content type="html"><![CDATA[<h1 id="题目大意"><a href="#题目大意" class="headerlink" title="题目大意"></a>题目大意</h1><p>考虑现在有$n \times (L+1)$个点,每个点用一个坐标$(x,y)$表示。($x \in [0,L],y \in [1,n]$)</p><p>一开始我们在$(0,x)$处,接下来每次可以跳若干步,从$(a,x)$跳到$(b,y)$($a < b$)的方案数为$w[a][b]$,求在跳了$x$次后到达$(L,y)$的方案数,$x$满足$x \bmod d=k$,对于$k\in[0,t-1]$都输出一个答案。</p><p>给定$n,w[][],L,x,y,d,t$,答案对质数$P$取模,保证有在模$P$意义下的$d$次单位根。</p><h1 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h1><p>考虑若对$x$的限制是$x=L$,那么这个问题可以直接使用矩阵快速幂解决。</p><p>加上题目里都明示要用单位根反演了,那我们考虑用单位根反演来解决这个问题。</p><p>我们可以比较容易地想到这个多项式:</p><script type="math/tex; mode=display">f(x)=\left( \begin{bmatrix} 1 \ 0 \ 0 \\ 0 \ 1 \ 0 \\ 0 \ 0 \ 1 \end {bmatrix} + Wx \right)^L</script><p>其中,$W$是一个矩阵,数值就是给定的w数组。</p><p>那么我们要求的东西就是这个:</p><script type="math/tex; mode=display">Ans_k=\sum_{i=0}^L [x \bmod k=t] [x^i]f(x) \qquad (for \ k \in[0,t-1])</script><p>然后就可以用矩阵乘法求答案了!</p><p>我们考虑使用单位根反演。注意:为了处理不是$d$的整次幂的情况,我们可以直接乘上一个$x^{d-k}$。</p><script type="math/tex; mode=display">\begin{aligned}Ans_k &= \frac{1}{d} \sum_{i=0} ^{d-1} f(\omega_{d}^{i})(\omega_d^{i})^{d-k} \\Ans_k &= \frac{1}{d} \sum_{i=0} ^{d-1} \omega_d^{-i\times k} \times f(\omega_{d}^{i})\end{aligned}</script><p>注意到:$i \times k= {i +k \choose 2} - {i \choose 2} - {k \choose 2}$。</p><p>代入可得</p><script type="math/tex; mode=display">\begin{aligned}Ans_k = \frac{1}{d} \sum_{i=0} ^{d-1} \omega_d^{ {k \choose 2} + {i \choose 2} - {i+k \choose 2} } \times f(\omega_{d}^{i}) \\Ans_k = \frac{\omega_d^{ {k \choose 2} } }{d} \sum_{i=0} ^{d-1} \omega_d^{-{i+k \choose 2} } \times ( f(\omega_{d}^{i}) \times \omega_d^{ {i \choose 2} } ) \end{aligned}</script><p>后面的用矩阵快速幂预处理。</p><p>差一定的卷积,请。</p><p>(要写任意模数卷积。)</p><p>代码请移步Github仓库。</p>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 数学 </tag>
<tag> 单位根反演 </tag>
<tag> FFT/NTT </tag>
</tags>
</entry>
<entry>
<title>[WC2019] 数树</title>
<link href="/2019/04/09/WC2019-%E6%95%B0%E6%A0%91/"/>
<url>/2019/04/09/WC2019-%E6%95%B0%E6%A0%91/</url>
<content type="html"><![CDATA[<h1 id="题目大意"><a href="#题目大意" class="headerlink" title="题目大意"></a>题目大意</h1><p>题目的模型是有两棵$n$个点树,求$y^{|T <em> 1 \cap T </em> 2 |}$。($T <em> 1,T </em> 2$分别是两棵树的边集。)</p><p>有三个部分,分别是:</p><ul><li>给定两棵树求答案。</li><li>给定一棵树,然后求另一棵树是$n^{n-2}$种情况时的答案和。</li><li>只给一个$n$,求出两棵树在所有情况下的答案和(共$(n^{n-2})^2$种情况)</li></ul><h1 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h1><p>我们一次考虑每个部分的做法。</p><h2 id="给定两棵树"><a href="#给定两棵树" class="headerlink" title="给定两棵树"></a>给定两棵树</h2><p>这部分只有普及组难度,随便用个$set$记一下就行了。</p><h2 id="给定一棵树"><a href="#给定一棵树" class="headerlink" title="给定一棵树"></a>给定一棵树</h2><p>我们不妨钦定一些$T <em> 1$中的边为必选边,那么考虑$T </em> 2$的方案数是多少(记为$F$)。</p><p>我们发现,加入一些必选边后,$T _ 2$被连成了若干连通块,我们假设形成了$m$个连通块(说明钦定了$n-m$条边)。</p><p>有一个很直观的想法就是这$m$个连通块的生成树个树(即$m^{m-2}$),但是显然算少了很多,因为两个连通块间的边的个数不是$1$,而是两个连通块大小的乘积。</p><p>那么我们不妨从$m^{m-2}$的本质来考虑这件事,众所周知,$m^{m-2}$的来源是$prufer$序列,那我们从$prufer$序列来审视这个问题。</p><p>我们发现,假设一个连通块的出现次数在$prufer$的出现次数为$d <em> i$,它的大小为$siz </em> i$,显然,它的度数为$d <em> i+1$,它对答案有一个$siz </em> i^{d _ i+1}$的乘法贡献。</p><p>我们现在不妨枚举每个连通块在$prufer$序列的出现次数并且枚举$prufer$序列,注意要处理多重集合的排列。</p><p>那么方案数很容易写出:</p><script type="math/tex; mode=display">F= m! \sum _ {\sum _ {i=1}^{m} d _ i=m-2} \prod _ {i=1}^{m} \frac{siz _ i^{d _ i+1}}{d _ i!}</script><p>我们随手化简一下,可以得到</p><script type="math/tex; mode=display">F= \prod _ {i=1}^{m} siz _ i \times m! \sum _ {\sum _ {i=1}^{m} d _ i=m-2} \prod _ {i=1}^{m} \frac{siz _ i^{d _ i}}{d _ i!}</script><p>我们接下来来考虑后面这一坨东西的组合意义,相当于我们先给每个连通块分配了一些位置,然后每个位置可以填$siz <em> i$种数字。那么我们可以直接考虑每个位置能填的数字,显然种类数就是$\sum </em> {i} siz _ i =n$,那么可以进一步化简得到最终形式。</p><script type="math/tex; mode=display">F = \prod _ {i=1} ^{m} siz _ i \times n^{m-2}</script><p>也就是说,我们现在可以暴力枚举边集,然后计算答案</p><script type="math/tex; mode=display">Ans = \sum _ {E \subset T _ 1} y^{n-|E|} n^{n-|E|-2} \prod _ {i=1} ^{n-|E|-2} siz _ i\\Ans = y^n n^{n-2} \sum _ {E \subset T _ 1} y^{-|E|} n^{-|E|} \prod _ {i=1} ^{n-|E|-2} siz _ i</script><p>接下来,为方便起见,我们令$y=y^{-1}$,最后统一乘$y^n$。</p><p>写个暴力,然后发现这玩意并不对,我们冷静分析一下,发现我们钦定出来的边集只是两个边集的交的一个子集,而不是最终的交。</p><p>那么接下来有两种处理方法,容斥和组合恒等式,这里只介绍组合恒等式的处理方法。</p><p>我们发现,我们设最终的交集为$|S|$,若我们钦定的集合的大小为$k$,那么这种大小的连通块对$S$的贡献就是.${|S| \choose k} \times val$。</p><p>我们知道有组合恒等式$y^{k} = \sum \limits _ {i=0} ^{k} {k \choose i} (y-1) ^ i$。</p><p>那么如果我们将权值$val$设置为$y-1$,再进行刚才的做法,发现每个集合的贡献恰好是$y^k$。</p><p>于是我们得到了一个指数级的做法,枚举边集。我们接下来考虑将复杂度降到$poly(n)$。</p><p>一个很自然的想法就是用树形$dp$来优化上述过程,我们发现,一个点状态只和这个点所在的连通块大小有关。那么可以设$f _ {x,s}$为考虑完以$x$为根的子树后,$x$所在的连通块的大小为$s$。这样,我们在合并儿子时考虑下$x$到儿子的这条边选不选,并且乘上相应的系数($1$或$y^{-1}n^{-1}$)进行转移即可,使用$siz$优化,复杂度为$\mathcal{O}(n^2)$。</p><p>这个做法的复杂度我们显然无法接受,考虑继续优化。</p><p>我们发现,$\prod{siz _ i}$的组合意义是从每个连通块分别选出一个点的方案数。那么我们可以这个组合意义设置新的$dp$状态。</p><p>我们设$f _ {x,0/1}$为考虑完$x$为根的子树,$x$所在连通块是否已经选点了的方案数,转移讨论一下就行了,注意每个点必须要选出一个点。复杂度$\mathcal{O}(n)$。</p><h2 id="给定零棵树"><a href="#给定零棵树" class="headerlink" title="给定零棵树"></a>给定零棵树</h2><p>这里我们继续沿用给定一棵树时的做法。</p><p>我们设$f(E)=\prod <em> {i=1} ^{m} siz </em> i \times n^{m-2}$,其中,$E$是一个边集,$m$表示将$E$中的边连接后形成的连通块个数,${siz}$是每个连通块的大小。</p><p>那么我们枚举一个边集$E$,且这个边集必须是某棵树的边集的子集,那么这个边集对答案的贡献是$f(E)^2 y^{|E|}$。</p><p>所以答案就是$\sum \limits _ {E} y^{|E|} f(E)^2 $。</p><p>我们不妨枚举$|E|$,我们设$g <em> i=\sum \limits </em> {|E|=i} f(E)$,答案可以进一步化简为$\sum \limits <em> {i=0}^{n-1} y^i g </em> i$。</p><p>那么我们接下来就要处理${g}$数组了。</p><p>由$f(E)$的计算式,我们不妨考虑枚举将$E$中的边连起来后每个连通块的大小${a}$,然后可以得到以下式子:</p><script type="math/tex; mode=display">g _ s = \sum _ {\sum _ {i=1}^{n-s}a _ i=n}\frac{n!}{(n-s)!} \prod _ {i=1}^{n-s} { \frac{a _ i^{a _ i-2}}{a _ i!}} ( \prod _ {i=1} ^{n-s} a _ i \times n^{n-s-2} )^2</script><p>解释下这个式子是怎么来的:</p><p>首先,我们需要让这些连通块内部都是连通的,就是$\prod \limits <em> {i=1}^{n-s} a </em> i^{a <em> i-2}$,然后,我们将$n$个点划分到这些集合中,就是多重集合的排列,体现在式子中就是$n! \prod \limits </em> {i=1}^{n-s} \frac{1}{a _ 1!}$,最后,这些连通块其实是无序的,但是我们在枚举大小的时候是作为有序的做的,所以我们要除掉$(n-s)!$,最后那个平方项就是$f(E)^2$。</p><p>然后我们将这个式子带到答案的式子中,并进行一番化简:</p><script type="math/tex; mode=display">\begin{aligned}Ans &= \sum _ {s=0}^{n-1} \sum _ {\sum _ {i=1}^{n-s}a _ i=n}\frac{n!}{(n-s)!} \prod _ {i=1}^{n-s} { \frac{a _ i^{a _ i-2}}{a _ i!}} ( \prod _ {i=1} ^{n-s} a _ i \times n^{n-s-2} )^2 \\Ans &= \sum _ {s=0}^{n-1} n!\frac{n^{2 * (n-2-s)}}{(n-s)!} \sum _ {\sum _ {i=1}^{n-s} a _ i = n} \prod _ {i=1}^{n-s} {\frac{a _ i^{a _ i}}{a _ i!}}\\Ans &= n! \sum _ {s=0}^{n-1} y^s \frac{n^{2 * (n-2-s)}}{(n-s)!} \sum _ {\sum _ {i=1}^{n-s} a _ i = n} \prod _ {i=1} ^{n-s} { \frac{a _ i^{a _ i}}{a _ i!}} \\Ans &= n! \sum _ {s=1}^{n} y^{(n-s)} \frac{n^{2 * (s-2)}}{s!} \sum _ {\sum _ {i=1}^{s} a _ i = n} \prod _ {i=1} ^{n-s} { \frac{a _ i^{a _ i}}{a _ i!}} \\Ans &= \frac{n!y^n}{n^4} \sum _ {s=1}^{n} y^{-s} \frac{n^{2 * s}}{s!} \sum _ {\sum _ {i=1}^{s} a _ i = n} \prod _ {i=1} ^{n-s} { \frac{a _ i^{a _ i}}{a _ i!}}\end{aligned}</script><p>注意,在第四个式子中,我用将$s$替换为了$n-s$。</p><p>然后我们发现第二个求和号的那个限制很难搞,但观察一下可以发现其实是个$\bf EGF$的形式,我们用$\bf EGF$来替换第二个求和号部分,并继续化简:</p><script type="math/tex; mode=display">\begin{aligned}Ans &= \frac{n!y^n}{n^4} \sum _ {s=1}^{n} y^{-s} \frac{n^{2*s}}{s!} [x^n] \left( {\sum _ {j \geqslant 1} \frac{j^{j}}{j!}} x^j \right) ^ s\\Ans &= \frac{n!y^n}{n^4} [x^n] \sum _ {s=1}^{n} \frac{\left( {\frac{n^2}{y} \sum _ {j \geqslant 1} \frac{j^{j}}{j!}} x^j \right) ^ s}{s!}\\Ans &= \frac{n!y^n}{n^4} [x^n] e^{\left( {\frac{n^2}{y} \sum _ {j \geqslant 1} \frac{j^{j}}{j!}} x^j \right)}\end{aligned}</script><p>然后写个多项式$\bf Exp$就做完了。</p><p>复杂度:$\mathcal{O}(n \log n)$</p><p><a href="https://github.com/Zhang-RQ/OI_Code/blob/master/LOJ/2983.cpp" target="_blank" rel="noopener">代码</a></p>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 计数 </tag>
<tag> 多项式 </tag>
</tags>
</entry>
<entry>
<title>[CodeForces 98E] Help Shrek and Donkey</title>
<link href="/2019/02/21/CodeForces-98E-Help-Shrek-and-Donkey/"/>
<url>/2019/02/21/CodeForces-98E-Help-Shrek-and-Donkey/</url>
<content type="html"><![CDATA[<h1 id="题目大意"><a href="#题目大意" class="headerlink" title="题目大意"></a>题目大意</h1><p>有两个人在玩一个游戏,规则如下:</p><ol><li><p>每个人的手上有一些牌,桌子上有一张牌,每个人只能看到自己手上的牌。(桌子上的看不到)</p></li><li><p>每张牌都不一样。</p></li><li><p>两个人轮流进行如下两个操作之一:</p><ul><li><p>猜桌子上的那张牌是什么,若猜对了,即获得胜利,否则算输掉比赛。</p></li><li><p>询问对方手中有没有一张牌,对方必须如实回答。</p></li></ul></li></ol><p>现在假设两个人都会执行最优策略,给定先后手的牌数$n,m$,询问两个人的胜率。</p><p>$n,m \leqslant 1000$</p><h1 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h1><p>不难发现,一个人若是进行询问操作,则有两种问法:</p><ol><li><p>询问自己手上没有的牌。(我们记这种询问为诚实的询问)</p></li><li><p>询问自己手上有的牌。(我们记这种询问为欺骗的询问)</p></li></ol><p>因为一个比较显然的思路是每次询问是问自己手上没有的牌(这样才能获得更多的信息)</p><p>然而我没也可以询问自己手上有的牌来误导对方自己手上没有这张牌,然后对方也没有这张牌的话就会认为桌子上是这张牌并猜是这张牌,然后他就输了。</p><p>然后对方也可以猜我这次的询问是不是诚实的询问(我们记为是否相信)。</p><h1 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h1><p>我们设$f(n,m)$为先手有$n$张牌,后手有$m$张牌时先手的胜率。</p><p>从刚才的分析中我们可以根据询问的诚实与否和是否相信来分为4种情况。</p><h2 id="情况的具体分析"><a href="#情况的具体分析" class="headerlink" title="情况的具体分析"></a>情况的具体分析</h2><h3 id="1-先手进行诚实询问,后手相信这次询问。"><a href="#1-先手进行诚实询问,后手相信这次询问。" class="headerlink" title="1. 先手进行诚实询问,后手相信这次询问。"></a>1. 先手进行诚实询问,后手相信这次询问。</h3><p>那么会有以下两种情况:</p><ol><li>$\frac{1}{m+1}$的概率猜到桌子上的牌,那么后手获胜(先手已经进行了操作,而后手已经知道了问的那张牌自己没有同时对方也没有,也就是桌子上的牌),对$f(n,m)$的贡献为$0$。</li><li>$\frac{m}{m+1}$的概率猜到后手手上的牌,那么先手知道了后手有问的那张牌(相当于后手失去了一张牌),后手知道了先手没有问的那张牌(没有得到新的信息),对$f(n,m)$的贡献是$\frac{m}{m+1} \times (1-f(m-1,n))$。(因为接下来先后手互换)</li></ol><h3 id="2-先手进行诚实询问,后手不相信这次询问。"><a href="#2-先手进行诚实询问,后手不相信这次询问。" class="headerlink" title="2.先手进行诚实询问,后手不相信这次询问。"></a>2.先手进行诚实询问,后手不相信这次询问。</h3><p>会出现以下两种情况:</p><ol><li>$\frac{1}{m+1}$的概率猜到桌子上的牌,那么后手会认为这张桌子上的牌会在先手的手中,也就是后手必败,对$f(n,m)$的贡献是$\frac{1}{m+1}$。</li><li>$\frac{m}{m+1}$的概率猜到后手手上的牌,那么后手肯定会相信这次询问,那么对答案的贡献就和上面一样了,即为$\frac{m}{m+1} \times (1-f(m-1,n))$。</li></ol><h3 id="3-先手进行欺骗询问,后手相信这次询问。"><a href="#3-先手进行欺骗询问,后手相信这次询问。" class="headerlink" title="3.先手进行欺骗询问,后手相信这次询问。"></a>3.先手进行欺骗询问,后手相信这次询问。</h3><p>那么后手就中招了,自己手上没有那张牌,且认为先手手上也没有问的那张牌,那么就会认为那张牌就是桌子上的牌,这样先手就会必胜,对$f(n,m)$的贡献是$1$。</p><h3 id="4-先手进行欺骗询问,后手不相信这次询问。"><a href="#4-先手进行欺骗询问,后手不相信这次询问。" class="headerlink" title="4.先手进行欺骗询问,后手不相信这次询问。"></a>4.先手进行欺骗询问,后手不相信这次询问。</h3><p>那么后手就会多知道先手手的一张牌(相当于先手失去了一张牌),对$f(n,m)$的贡献是$1-f(m,n-1)$。</p><h2 id="做法"><a href="#做法" class="headerlink" title="做法"></a>做法</h2><p>不难发现,这是一种混合策略的博弈游戏,就需要纳什均衡的那一套理论。</p><p>我们不妨假设先手进行诚实询问的概率为$p$,则进行欺骗询问的概率就是$1-p$。</p><p>那么后手选相信时对答案的贡献就是$p \times \frac{m}{m+1} \times (1-f(m-1,n)) + (1-p) \times 1$。</p><p>后手选不相信时对答案的贡献就是$p \times (\frac{1}{m+1}+\frac{m}{m+1} \times (1-f(m-1,n))) +(1-p) \times 1-f(m,n-1)$。</p><p>根据纳什均衡的理论,先手的最优决策点就是纳什均衡点,就是无论后手如何选择,答案均不会比当前情况更差的那个$p$,在这里就是令上下式子相等的那个$p$,解下方程就行了。</p><p>最后我们再记忆化一下就可以做到$\mathcal{O}(nm)$了。</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><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><bits/stdc++.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN=<span class="number">1010</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">bool</span> vis[MAXN][MAXN];</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">double</span> f[MAXN][MAXN];</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">long</span> <span class="keyword">double</span> <span class="title">F</span><span class="params">(<span class="keyword">int</span> n,<span class="keyword">int</span> m)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">if</span>(vis[n][m]) <span class="keyword">return</span> f[n][m];</span><br><span class="line">vis[n][m]=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">if</span>(!n) <span class="keyword">return</span> f[n][m]=<span class="number">1.0</span>/(m+<span class="number">1</span>);</span><br><span class="line"><span class="keyword">if</span>(!m) <span class="keyword">return</span> f[n][m]=<span class="number">1</span>;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">double</span> k1=<span class="number">1.0</span>*m/(m+<span class="number">1</span>)*(<span class="number">1</span>-F(m<span class="number">-1</span>,n))<span class="number">-1</span>,k2=<span class="number">1.0</span>*m/(m+<span class="number">1</span>)*(<span class="number">1</span>-F(m<span class="number">-1</span>,n))+<span class="number">1.0</span>/(m+<span class="number">1</span>)+F(m,n<span class="number">-1</span>)<span class="number">-1</span>;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">double</span> x=(-F(m,n<span class="number">-1</span>))/(k1-k2);</span><br><span class="line"><span class="keyword">return</span> f[n][m]=x*(<span class="number">1.0</span>*m/(m+<span class="number">1</span>)*(<span class="number">1</span>-F(m<span class="number">-1</span>,n)))+<span class="number">1</span>-x;</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="function"></span>{</span><br><span class="line"><span class="keyword">int</span> n,m;</span><br><span class="line"><span class="built_in">cin</span>>>n>>m;</span><br><span class="line"><span class="keyword">long</span> <span class="keyword">double</span> Ans=F(n,m);</span><br><span class="line"><span class="built_in">cout</span><<fixed<<setprecision(<span class="number">15</span>)<<Ans<<<span class="string">" "</span><<<span class="number">1</span>-Ans<<<span class="built_in">endl</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 数学 </tag>
<tag> 博弈论 </tag>
<tag> 纳什均衡 </tag>
</tags>
</entry>
<entry>
<title>多项式全家桶</title>
<link href="/2018/12/20/%E5%A4%9A%E9%A1%B9%E5%BC%8F%E5%85%A8%E5%AE%B6%E6%A1%B6/"/>
<url>/2018/12/20/%E5%A4%9A%E9%A1%B9%E5%BC%8F%E5%85%A8%E5%AE%B6%E6%A1%B6/</url>
<content type="html"><![CDATA[<h1 id="引言"><a href="#引言" class="headerlink" title=" 引言"></a> 引言</h1><p>众所周知,多项式在OI中是一项很实用的技能,现在将多项式的有关知识总结一下。</p><h1 id="前置技能"><a href="#前置技能" class="headerlink" title="前置技能"></a>前置技能</h1><ol><li>认识汉字以及常用的基本词汇,如果此项有问题,请移步<a href="http://www.hydcd.com/" target="_blank" rel="noopener">这里</a></li><li>基本数学知识(四则运算,多项式的概念等),如果此项有问题,请移步<a href="http://www.dzkbw.com/books/rjb/xiaoxue-shuxue/" target="_blank" rel="noopener">这里</a></li><li>一些高中数学知识和高数知识(泰勒展开等),如果此项有问题,请自行学习</li><li>FFT、NTT等多项式基本算法</li></ol><h1 id="符号及约定"><a href="#符号及约定" class="headerlink" title="符号及约定"></a>符号及约定</h1><ol><li>若不做特殊说明,$n$代指多项式的长度(次数+1)</li><li>$[x^i]f(x)$表示多项式$f(x)$的$i$次项系数。</li><li>若不做特殊说明,本文的运算均在$998244353$或其他费马素数的剩余系下的意义进行。</li></ol><h1 id="多项式加减法"><a href="#多项式加减法" class="headerlink" title="多项式加减法"></a>多项式加减法</h1><p>直接$\mathcal{O}(n)$。</p><h1 id="多项式乘法"><a href="#多项式乘法" class="headerlink" title="多项式乘法"></a>多项式乘法</h1><p>暴力卷积 $\mathcal{O}(n^2)$。</p><p>使用NTT可加速至$\mathcal{O}(n \log n)$</p><h1 id="多项式求逆"><a href="#多项式求逆" class="headerlink" title="多项式求逆"></a>多项式求逆</h1><p>首先,求逆必须要在$\bmod x^k$的意义下进行。</p><p>现在假设我们已知$n$次多项式$f(x)$,现在要求$g(x)$使得$ f(x) \times g(x) \equiv1 \pmod {x^{n+1}} $。</p><p>我们使用倍增算法。</p><p>假设已知$g_0(x)$使得$f(x) \times g_0(x) \equiv 1 \pmod{x^{\frac{n}{2}}}$,</p><p>现在要求$g(x)$使得$f(x) \times g(x) \equiv 1 \pmod{x^n}$。</p><script type="math/tex; mode=display">\begin{aligned}\becausef(x) \times g_0(x) & \equiv 1 & \pmod{x^{\frac{n}{2}}} \\f(x) \times g(x) & \equiv 1 & \pmod{x^{\frac{n}{2}}} \\\therefore g(x)-g_0(x) & \equiv 0 & \pmod{x^{\frac{n}{2}}}\\\text{两边平方,得到} (g(x)-g_0(x))^2 & \equiv 0 & \pmod{x^{n}}\\g^2(x)-2g(x)g_0(x)+g_0^2(x) & \equiv 0 & \pmod{x^{n}}\\\text{两边同乘f(x),得到} g(x)-2g_0(x)+g_0^2(x) \times f(x) & \equiv 0 & \pmod{x^{n}}\\g(x) & \equiv 2g_0(x)-g_0^2(x) \times f(x) & \pmod{x^{n}}\end{aligned}</script><p>于是我们得到了$g(x) \equiv 2g_0(x)-g_0^2(x) \pmod{x^{n}}$,就可以倍增了。</p><p>倍增起点是$g(x)=1 \pmod{x}$,倍增终点是$k>n$,$k=2^i$,就是我们在倍增时候的那个次数。</p><p>复杂度:$T(n)=T(\frac{n}{2})+O(n \log n)$得到最终复杂度为$O(n \log n)$</p><h1 id="多项式除法"><a href="#多项式除法" class="headerlink" title="多项式除法"></a>多项式除法</h1><p>多项式除法同样是在$\bmod x^k$的意义下进行的。</p><p>假设我们现在已知$n$次多项式$f(x)$和$m$次多项式$g(x)$,现在请求出多项式$h(x)$和$r(x)$,满足下列两个条件</p><ol><li><p>$f(x) \equiv g(x) \times h(x) +r(x) \pmod{x^{n+1}}$</p></li><li><p>$h(x)$的次数为$n-m$,$r(x)$的次数小于$m$</p></li></ol><p>我们来考虑一个操作:</p><p>另$g(x)=x^nf(\frac{1}{x})$,则不难发现,其实$g(x)$的系数就是将$f(x)$的系数翻转过来了。</p><p>我们设$\hat f(x)=x^n f(\frac{1}{x})$</p><p>那么我们不妨这样处理:</p><script type="math/tex; mode=display">\begin{aligned}f(x) & \equiv g(x) \times h(x) +r(x) & \pmod{x^{n+1}} \\f(\frac{1}{x}) & \equiv g(\frac{1}{x}) \times h(\frac{1}{x}) +r(\frac{1}{x}) & \pmod{x^{n+1}} \\x^nf(\frac{1}{x}) & \equiv x^n g(\frac{1}{x}) \times h(\frac{1}{x}) + x^nr(\frac{1}{x}) & \pmod{x^{n+1}} \\x^nf(\frac{1}{x}) & \equiv x^m g(\frac{1}{x}) \times x^{n-m} h(\frac{1}{x}) + x^nr(\frac{1}{x}) & \pmod{x^{n+1}} \\\hat f(x) & \equiv \hat g(x) \times \hat h(x) +x^{n-m+1} \hat r(x) & \pmod{x^{n+1}} \\\text{接下来在} & \bmod x^{n-m+1}\text{的意义下进行} \\\hat f(x) & \equiv \hat g(x) \times \hat h(x) & \pmod{x^{n-m+1}} \\\hat h(x) & \equiv \hat f(x) \times \hat g^{-1}(x) & \pmod{x^{n-m+1}} \\\end{aligned}</script><p>于是我们就求出来了$h(x)$,那么显然有$r(x) \equiv f(x) - g(x) \times h(x)$</p><p>复杂度显然与多项式求逆一致。</p><h1 id="多项式求导"><a href="#多项式求导" class="headerlink" title="多项式求导"></a>多项式求导</h1><script type="math/tex; mode=display">[x^i]f'(x)=(i+1) \times [x^{i+1}]f(x)</script><p>$\mathcal{O}(n)$</p><h1 id="多项式积分"><a href="#多项式积分" class="headerlink" title="多项式积分"></a>多项式积分</h1><script type="math/tex; mode=display">[x^i]\int f(x) = \frac{1}{i}[x^{i-1}]f(x)</script><p>$\mathcal{O}(n)$</p><h1 id="多项式牛顿迭代"><a href="#多项式牛顿迭代" class="headerlink" title="多项式牛顿迭代"></a>多项式牛顿迭代</h1><p>在这个问题中,我们已知函数$f(x)$,现在要求函数$g(x)$,使得$f(g(x)) \equiv 0 \pmod{x^{n+1}}$。</p><p>我们考虑倍增,假设我们已经求出了$g_0(x)$使得$f( g_0(x) ) \equiv 0 \pmod{x^{\frac{n}{2}}}$</p><p>我们要求$g(x)$使得$f( g(x) ) \equiv 0 \pmod{x^{n}}$</p><p>我们在$g_0(x)$出泰勒展开,我们可以得到</p><script type="math/tex; mode=display">\begin{aligned}f(g(x)) & = f(g_0(x)) \\& + f'(g_0(x)) (g(x)-g_0(x)) \\& + \frac{f''(g_0(x))(g(x)-g_0(x))^2 }{2!}\\& + \cdots \end{aligned}</script><p>由于我们在$\bmod x^{n}$的意义下进行,并且$g(x)-g_0(x)$的只有前$\frac{n}{2}$项不为$0$,</p><p>所以从第三项开始的东西都被消去了。</p><p>于是得到</p><script type="math/tex; mode=display">\begin{aligned}f(g(x)) & \equiv f(g_0(x)) + f'(g_0(x)) (g(x)-g_0(x)) \pmod {x^n}\\0 & \equiv f(g_0(x)) + f'(g_0(x)) (g(x)-g_0(x)) \pmod {x^n}\\g(x) & \equiv g_0(x) - \frac{f(g_0(x))}{f'(g_0(x))} \pmod {x^n}\\\end{aligned}</script><p>就可以了</p><h1 id="多项式ln"><a href="#多项式ln" class="headerlink" title="多项式ln"></a>多项式ln</h1><p>多项式ln可以看成将多项式带入了麦克劳林级数中。</p><p>具体定义是:</p><script type="math/tex; mode=display">\ln (1 - A(z)) = -\sum_{i \geq 1} \frac{A^i(z)}{i}</script><p>也就是说, 我们在计算$\ln f(x)$时,必须满足$[x^0]f(x)=1$。</p><p>接下来考虑怎么做。</p><script type="math/tex; mode=display">\begin{aligned}g(x) & \equiv \ln(f(x)) \pmod {x^{n+1}} \\g'(x) & \equiv \frac{f'(x)}{f(x)} \pmod {x^{n+1}}\end{aligned}</script><p>最后再将$g$积分回去即可。</p><p>只需要多项式求逆+多项式求导/积分。</p><p>复杂度$O(n \log n)$</p><h1 id="多项式exp"><a href="#多项式exp" class="headerlink" title="多项式exp"></a>多项式exp</h1><p>多项式exp可以看成将多项式带入了麦克劳林级数中。</p><p>具体定义是:</p><script type="math/tex; mode=display">\exp(A(z)) = e^{A(z)} = \sum_{i \geq 0} \frac{A^i(z)}{i!}</script><p>设$g(x)=e^{f(x)}$,两边取对数,得到$\ln g(x)=f(x)$,进一步可得到$ln(g(x))-f(x)=0$</p><p>也就是说,我们现在有函数$h(x)=ln(x)-f(z)$,现在要求$g(x)$使得$h(g(x))=0$。</p><p>显然有$h’(x)=\frac{1}{x}$,也就是说$h’(g(x))=\frac{1}{g(x)}$。</p><p>根据牛顿迭代的理论,这东西显然是要倍增的,并且能够得到递推式</p><script type="math/tex; mode=display">\begin{aligned}g(x) & \equiv g_0(x) - \frac{h(g_0(x))}{h'(g_0(x))} & \pmod {x^n} \\g(x) & \equiv g_0(x) - h(g_0(x)) \times g_0(x) & \pmod {x^n} \\g(x) & \equiv g_0(x) \times (1 - h(g_0(x))) & \pmod {x^n} \\\text{带入}&h(x)\text{的定义,得到} \\g(x) & \equiv g_0(x) \times (1 - \ln (g_0(x)) + f(x)) & \pmod {x^n} \\\end{aligned}</script><p>于是就可以递推了。</p><p>复杂度$O(n \log n)$</p><p>所有代码均可以在<a href="https://github.com/Zhang-RQ/OI_Code/tree/master/%E6%A8%A1%E6%9D%BF" target="_blank" rel="noopener">这里</a>找到</p><h1 id="多项式开根"><a href="#多项式开根" class="headerlink" title="多项式开根"></a>多项式开根</h1><p>算法一:$\sqrt{f(x)}=e^{\frac{1}{2} \ln f(x)}$</p><p>算法二:牛顿迭代</p><p>我们现在要求$g(x)$使得$g^2(x)=f(x)$。</p><p>构造函数$h$满足$h(g(x))=g^2(x)-f(x)$,问题转化为了求$g(x)$满足$h(g(x))=0$。</p><p>假设我们已经得到了$\pmod {x^\frac{n}{2}}$时的答案$g_0(x)$</p><p>直接套用牛顿迭代的式子,我们可以得到</p><script type="math/tex; mode=display">\begin{aligned}g(x) & \equiv g_0(x) - \frac{f(g_0(x))}{f'(g_0(x))} \pmod {x^n} \\g(x) & \equiv g_0(x) - \frac{g_0^2(x)-f(x)}{2g_0(x)} \pmod {x^n} \\g(x) & \equiv \frac{g_0^2(x)+f(x)}{2g_0(x)} \pmod {x^n}\end{aligned}</script><p>倍增的起点是$n=1$,一般来说,$f(x)$ 的常数项为1或0,否则需要计算二次剩余。</p>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> 数学 </tag>
<tag> 多项式 </tag>
</tags>
</entry>
<entry>
<title>单位根反演</title>
<link href="/2018/08/13/%E5%8D%95%E4%BD%8D%E6%A0%B9%E5%8F%8D%E6%BC%94/"/>
<url>/2018/08/13/%E5%8D%95%E4%BD%8D%E6%A0%B9%E5%8F%8D%E6%BC%94/</url>
<content type="html"><![CDATA[<h1 id="引子"><a href="#引子" class="headerlink" title="引子"></a>引子</h1><p>假设现在我们要求一个式子 </p><script type="math/tex; mode=display">\sum _ {i=0}^{n} {n \choose 2i}</script><p>不妨构造二项式 </p><script type="math/tex; mode=display">(1+x)^n=\sum _ {i=0}^{n} {n \choose i} x^i</script><p>我们现在将$x=1$,$x=-1$ 带入,则有 </p><script type="math/tex; mode=display">\begin {align}2^n &= \sum _ {i=0}^{n} {n \choose i} \\0 &= \sum _ {i=0}^{n} (-1)^i {n \choose i}\end {align}</script><p>两式相加,则有 </p><script type="math/tex; mode=display">2^n=2*\sum _ {i=0}^{\lfloor \frac{n}{2} \rfloor} {n \choose 2i}</script><p>问题已经解决,$Ans=2^{2*n-1}$。 </p><p>那如果我们现在想计算 </p><script type="math/tex; mode=display">\sum _ {i=0} ^{n} {n \choose ki}</script><p>该怎么办? </p><h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>单位根反演就是做以上工作的东西。 </p><p>简而言之,如果能快速求出某个多项式的点值,那我们就可能能求出$x$的特定倍数幂的系数和。 </p><p>形式化的,我们可以求</p><script type="math/tex; mode=display">\sum _ {i=0}^{\lfloor \frac{n}{k} \rfloor} [x^{ik}] f(x)</script><h1 id="知识储备"><a href="#知识储备" class="headerlink" title="知识储备"></a>知识储备</h1><h2 id="单位根"><a href="#单位根" class="headerlink" title="单位根"></a>单位根</h2><p>根据$FFT$的前置知识,我们可以知道,对于一个$n$,若有$x^n-1=0$,则称$x$是$n$次单位根,记为$\omega _ n$。</p><p>单位根在复平面上的分布将单位圆均分为$n$份,在第一象限的最靠近实轴的单位根记为$\omega <em> n^1$,一般也可记为$\omega </em> {n}$。其余的按逆时针排序,分别为$\omega _ n^{2 \cdots n-1}$ </p><p>所以我们不难发现如下几个性质: </p><ol><li><p>$ \omega <em> n^i +\omega </em> n^{i+n/2} (2|n)$ </p></li><li><p>$\omega <em> n^i=\omega </em> n^{i \% n}$ </p></li><li><p>$\omega <em> {kn}^{ki}=\omega </em> {n}^{i}$ </p></li></ol><p>由于性质3的存在,我们可以定义本原单位根。</p><p>本原单位根的定义是:若$\omega,n$满足$\omega^n-1=0$,且$n$是最小满足条件的,则称$\omega$是$n$的本原单位根。</p><p>我们不难发现,对于单位根$\omega <em> {n}^{i}$,若$\gcd(n,i)==1$,则$\omega </em> n^i$一定是n的本原单位根。</p><p>否则,设$d=\gcd(i,n)$,则$\omega <em> {n}^{i}=\omega </em> {n’d}^{i’d}=\omega <em> {n’}^{i’}$,$(\omega </em> {n’}^{i’})^{n’}-1=0$。并不是$n$的本原单位根。</p><p>性质:</p><script type="math/tex; mode=display">\forall k,[n \mid k]=\frac{1}{n}\sum _ {i=0}^{n-1} \omega _ {n}^{ik}</script><p>证明:</p><p>若$n \mid k$,则有</p><script type="math/tex; mode=display">Ans=\frac{1}{n} \sum _ {i=0}^{n-1} \omega _ {n}^{ink'}=\frac{1}{n}\sum _ {i=0}^{n-1} 1=1</script><p>否则,这玩意是个等比数列求和,根据高中知识,我们有 </p><script type="math/tex; mode=display">Ans=\frac{1}{n} \frac{\omega _ {n}^{0}-\omega _ {n}^{nk}}{1-\omega _ {n}^{k}}=0</script><p>得证。 </p><h1 id="应用"><a href="#应用" class="headerlink" title="应用"></a>应用</h1><p>现在我们考虑一开始提出的那个问题,求 </p><script type="math/tex; mode=display">\sum _ {i=0} ^{n} {n \choose ki}</script><p>这个就相当于在求(设$N=nk$) </p><script type="math/tex; mode=display">f(x)=\sum _ {i=0}^{N} {N \choose i} x^i</script><p>的次数为$k$的倍数的项的系数和。 </p><p>我们不妨设 </p><script type="math/tex; mode=display">f(x)=\sum _ {i=0}^{N} a _ i x^i<</script><p>那我们只需要求 </p><script type="math/tex; mode=display">\begin {align}Ans &= \sum _ {i=0}^{N} ([x^i]f(x)) [k \mid i] \\ &= \sum _ {i=0}^{N} ([x^i]f(x)) \frac{1}{k} \sum _ {j=0}^{k-1} \omega _ {k}^{ij} \\ &= \sum _ {i=0}^{N} ([x^i]f(x)) \frac{1}{k}\sum _ {j=0}^{k-1} (\omega _ {k}^{j})^i \\ &= \sum _ {i=0}^{N} a _ i \sum _ {j=0}^{k-1} (\omega _ {k}^{j})^i\\ &= \sum _ {j=0}^{k-1} \sum _ {i=0}^{N} (\omega _ {k}^{j})^i\\ &= \frac{1}{k}\sum _ {j=0}^{k-1} f(\omega _ {k}^{j})\end{align}</script><p>即可。 </p><p>同时注意到 </p><script type="math/tex; mode=display">f(x)=(x+1)^n</script><h1 id="例题"><a href="#例题" class="headerlink" title="例题"></a>例题</h1><h2 id="LOJ-6485-LJJ-学二项式定理"><a href="#LOJ-6485-LJJ-学二项式定理" class="headerlink" title="[LOJ 6485] LJJ 学二项式定理"></a>[LOJ 6485] LJJ 学二项式定理</h2><p><a href="https://loj.ac/problem/6485" target="_blank" rel="noopener">Link</a></p><h3 id="题意"><a href="#题意" class="headerlink" title="题意"></a>题意</h3><p>给定$n,s,a <em> 0,a </em> 1,a <em> 2,a </em> 3$,求 </p><script type="math/tex; mode=display">[\sum _ {i=0}^{n} ({n \choose i} s^i a _ {i \bmod4}) ] \bmod 998244353</script><h3 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h3><p>我们不妨不关注$a$数组部分,先构造二项式 </p><script type="math/tex; mode=display">\begin {align}f(x) &= \sum _ {i=0}^{n} {n \choose i} s^i x^i *1^{n-i} \\&= (sx+1)^n\end {align}</script><p>现在只要分别求出$f(x)$除$4$余$0 \cdots 3$的系数之和即可,直接套用之前所讲的方法即可。 </p><p>需要注意,在模$P$意义下,设$g$为$P$的原根,则$\omega _ {n}^{1}=g^{\frac{P-1}{n}}$。 </p><p>第二种构造方法: </p><script type="math/tex; mode=display">\begin {align}f(x) &= \sum _ {i=0}^{n} {n \choose n-i} s^{n-i} x^i \\f(x) &=(s+x)^n\end {align}</script><p>注意,这里使用了$n-i$替换了$i$,所以要处理一下$a$数组的下标。 </p>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> 数学 </tag>
</tags>
</entry>
<entry>
<title>常系数齐次线性递推学习笔记</title>
<link href="/2018/06/28/%E5%B8%B8%E7%B3%BB%E6%95%B0%E9%BD%90%E6%AC%A1%E7%BA%BF%E6%80%A7%E9%80%92%E6%8E%A8%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<url>/2018/06/28/%E5%B8%B8%E7%B3%BB%E6%95%B0%E9%BD%90%E6%AC%A1%E7%BA%BF%E6%80%A7%E9%80%92%E6%8E%A8%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>什么是常系数齐次线性递推?</p><p>设有数列${a <em> 0,a </em> 1,a <em> 2 \cdots }$满足递推关系$a </em> n=\sum\limits <em> {i=1}^{k}a </em> {n-i}*f _ i$,则称该数列满足k阶齐次线性递推关系。</p><h1 id="矩阵乘法"><a href="#矩阵乘法" class="headerlink" title="矩阵乘法"></a>矩阵乘法</h1><p>这个很普及的东西还是提一下吧。</p><p>假设我们有一个满足k阶齐次线性递推关系的数列${a <em> 0,a </em> 1,a <em> 2 \cdots}$,它满足的齐次线性递推关系为$a </em> n=\sum\limits <em> {i=1}^{k}a </em> {n-i}*f <em> i$,现在我们要求$a </em> n$。</p><p>假设我们现在维护着一个列矩阵,它的行数为k。</p><script type="math/tex; mode=display">A=\begin{bmatrix} a _ {n} \\ a _ {n-1} \\ \cdots \\ a _ {n-k+2} \\ a _ {n-k+1}\end{bmatrix}</script><p>我们考虑如何让这个矩阵的所有元素都向前递推一格,不难设计出k行k列的转移矩阵。</p><script type="math/tex; mode=display">M=\begin{bmatrix} f _ 1 &f _ 2 &f _ 3 &f _ 4 & \cdots &f _ {k-2} &f _ {k-1} \\ 1 &0 &0 &0 & \cdots &0 &0 \\ 0 &1 &0 &0 & \cdots &0 &0\\ \cdots & \cdots & \cdots & \cdots & \cdots & \cdots & \cdots\\ 0 &0 &0 &0 & \cdots &1 &0\end{bmatrix}</script><p>我们可以得到</p><script type="math/tex; mode=display">\begin{bmatrix} f _ 1 &f _ 2 &f _ 3 &f _ 4 & \cdots &f _ {k-2} &f _ {k-1} \\ 1 &0 &0 &0 & \cdots &0 &0 \\ 0 &1 &0 &0 & \cdots &0 &0\\ \cdots & \cdots & \cdots & \cdots & \cdots & \cdots & \cdots\\ 0 &0 &0 &0 & \cdots &1 &0\end{bmatrix}\times\begin{bmatrix} a _ {n-1} \\ a _ {n-2} \\ \cdots \\ a _ {n-k+1} \\ a _ {n-k}\end{bmatrix}=\begin{bmatrix} a _ {n} \\ a _ {n-1} \\ \cdots \\ a _ {n-k+2} \\ a _ {n-k+1}\end{bmatrix}</script><p>现在我们要求$a _ n$,根据矩阵乘法的结合律,易得到:</p><script type="math/tex; mode=display">\left( \begin{bmatrix} f _ 1 &f _ 2 &f _ 3 &f _ 4 & \cdots &f _ {k-2} &f _ {k-1} \\ 1 &0 &0 &0 & \cdots &0 &0 \\ 0 &1 &0 &0 & \cdots &0 &0\\ \cdots & \cdots & \cdots & \cdots & \cdots & \cdots & \cdots\\ 0 &0 &0 &0 & \cdots &1 &0 \end{bmatrix}\right) ^n \times\begin{bmatrix} a _ {k-1} \\ a _ {k-2} \\ \cdots \\ a _ {1} \\ a _ {0}\end{bmatrix}\times\begin{bmatrix} a _ {n+k-1} \\ a _ {n+k-2} \\ \cdots \\ a _ {n+1} \\ a _ {n}\end{bmatrix}</script><p>所以我们只需要算出$M^n \times A$,然后取最后一个数就可以了。</p><p>可以使用矩阵快速幂,复杂度$\mathcal{O}(k^3log _ 2n)$</p><h1 id="特征多项式"><a href="#特征多项式" class="headerlink" title="特征多项式"></a>特征多项式</h1><h2 id="特征值,特征向量"><a href="#特征值,特征向量" class="headerlink" title="特征值,特征向量:"></a>特征值,特征向量:</h2><p>若有常数$\lambda$,向量$\vec v$,满足$\lambda\vec v=A\vec v$ ,则称向量$\vec v$为矩阵$A$的一组特征向量,$\lambda$为矩阵$A$的一组特征值。 </p><p><strong>秩为k</strong>的矩阵有<strong>k组线性不相关</strong>的特征向量。 </p><h2 id="特征多项式-1"><a href="#特征多项式-1" class="headerlink" title="特征多项式"></a>特征多项式</h2><p>对关系式进行变换:$(\lambda I-A)\vec v=0$。 </p><p>这个等式有解的充要条件是$det(\lambda I-A)=0$,大致可以看做向量被拍扁之类的。 </p><p>可以得到一个$k$次多项式,这个多项式的值等于$0$时把这个方程称为矩阵$A$的<strong>特征方程</strong>。这个多项式称为矩阵$A$的<strong>特征多项式</strong>。 </p><p>特征多项式记为$f(x)=det(\lambda I-A)$。</p><p>其中,$det()$为行列式函数,$I$为单位矩阵。</p><p>$k$个解自然就是$k$个特征值。(并不需要解出来,怎么处理后面会说)</p><p>跟据算数基本定理,最终的多项式有$k$个解,可以写作$f(x)=\prod <em> i(\lambda </em> i-x)$。</p><h2 id="Cayley-Hamilton定理"><a href="#Cayley-Hamilton定理" class="headerlink" title="Cayley-Hamilton定理"></a>Cayley-Hamilton定理</h2><p>根据Cayley-Hamilton定理,可知$f(A)=O$,$O$为0矩阵。</p><p>下面给出一个简单证明:</p><p>$f(A)=\prod\limits <em> {i}(\lambda </em> {i} I - A)$</p><p>考虑将$f(A)$得到的矩阵分别乘特征向量,如果最后都得到了$0$矩阵,因为这几个特征向量线性不相关,那么可证明$f(A)$乘以任意向量都会得到$0$矩阵,从而$f(A)$为$0$矩阵。 </p><p>现在问题转换为证明$f(A)$乘任意特征向量都会得到$0$矩阵。</p><p>先证明:$(\lambda <em> i I-A) \times (\lambda </em> j I -A) = (\lambda <em> j I -A) \times (\lambda </em> i I -A)$ </p><p>展开即可,不再赘述。</p><p>现在考虑任意一个特征向量 $\vec v _ i$</p><script type="math/tex; mode=display">f(A) \times \vec v _ {i} = \prod _ {j!=i} \times (\lambda _ {j} I - A) \times (\lambda _ i I -A) \times \vec v _ {i} \\\text{由特征向量和特征值的定义可知,} (\lambda _ i I -A) \times \vec v _ {i}=0。 \\\therefore f(A) \times \vec v _ {i} =O</script><p>证毕。</p><h2 id="优化递推"><a href="#优化递推" class="headerlink" title="优化递推"></a>优化递推</h2><p>设转移矩阵为$M$。</p><p>根据矩阵快速幂那套理论,我们只要求出来$M^n$就可以了。</p><p>我们考虑$M$的特征多项式$f(x)$,这是一个$k$次多项式。</p><p>我们将$M$带入,就会得到一个关于$M$的$k$次多项式。</p><p>我们可以将$M^n$分解为$M^n=f(M) \times g(M) +R(M)$。</p><p>由于$f(M)=O$,所以$M^n=R(M)$,$R(M)$是一个次数不超过$k-1$的多项式。</p><p>也就是说,我们只要求出来$M^n \% f(M)$ 就万事大吉了。</p><p>但是我们怎么求呢?</p><p>我们考虑快速幂的过程(就是倍增)。</p><p>假设我们现在已知 $g(M)=M^{2^i} \% f(M)$,现在要求$h(M)= M^{2^{i+1}} \% f(M)$。</p><p>一个直接的想法就是令$H(M)=g(M) \times g(M)$。</p><p>但是这样做,$H(M)$ 的次数是$2k-2$的。</p><p>那我们考虑原本的递推关系,$a <em> n=\sum\limits </em> {i=1}^{k}a <em> {n-i}*f </em> i$。</p><p>不难得到$M^n=\sum\limits <em> {i=1} ^{k} M^{n-i} \times f </em> {i}$。</p><p>所以我们可以用这个式子将多余出来的系数都向前压一位。</p><p>这样我们就得到了一个$\mathcal{O}(k^2\log _ 2 n)$的做法。</p><p>那有没有优化的余地呢?<br>我们从倍增的过程入手,可以发现$H(M)=g(M) \times g(M)$的过程可以由FFT加速至$\mathcal{O}(klog _ 2k)$。</p><p>现在只要解决压系数的过程就行了。</p><p>我们只要让$h(M) =H(M) \% f(M)$就行了。</p><p>等等,$f(M)$怎么求?</p><p>根据定义,$f(x)=det(xI - M)$,得到</p><script type="math/tex; mode=display">f(x) = |x I - M| = \begin{bmatrix} x- a _ 1 & -a _ 2 & -a _ 3 & \cdots & -a _ {k - 2} & -a _ {k - 1} & -a _ k \\ -1 & x & 0 & \cdots & 0 & 0 & 0 \\ 0 & -1 & x & \cdots & 0 & 0 & 0 \\ 0 & 0 & -1 & \cdots & 0 & 0 & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots & \vdots \\ 0 & 0 & 0 & \cdots & -1 & x & 0 \\ 0 & 0& 0 & \cdots & 0 & -1 & x\end{bmatrix}</script><p>我们对其进行第一列展开,得到</p><script type="math/tex; mode=display">f(x) = (x - a _ 1)M _ {11} + (-a _ 2)M _ {12} + \cdots + (-a _ k)M _ {1n} = x ^ k - a _ 1 x ^ {k - 1} - a _ 2x ^ {k - 2} - \cdots - a _ k</script><p>$M _ {i,j}$代表$M$的算术余子式。</p><p>只要直接上多项式取模就行了。</p><p>最后的总复杂度$\mathcal{O}(k \log <em> 2 k \log </em> 2 n)$</p><p>我们手动模拟一下多项式取模的过程,其实可以发现我们手动向前压的过程就是在暴力取模。</p><p>附上<a href="https://www.lydsy.com/JudgeOnline/problem.php?id=4161" target="_blank" rel="noopener">BZOJ4161</a>的$\mathcal{O}(k^2\log _ 2 n)$代码</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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></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"><cstdlib></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cctype></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cassert></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 class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> P=<span class="number">1000000007</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN=<span class="number">4010</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> n,k,ans;</span><br><span class="line"><span class="keyword">int</span> f[MAXN],h[MAXN];</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> a[MAXN];</span><br><span class="line"> Matrix (){<span class="built_in">memset</span>(a,<span class="number">0</span>,<span class="keyword">sizeof</span> a);}</span><br><span class="line"> <span class="keyword">int</span>& <span class="keyword">operator</span> [] (<span class="keyword">const</span> <span class="keyword">int</span> &i) {<span class="keyword">return</span> a[i];}</span><br><span class="line"> <span class="keyword">int</span> <span class="keyword">operator</span> [] (<span class="keyword">const</span> <span class="keyword">int</span> &i) <span class="keyword">const</span> {<span class="keyword">return</span> a[i];}</span><br><span class="line"> <span class="keyword">inline</span> Matrix <span class="keyword">operator</span> * (<span class="keyword">const</span> Matrix &rhs) <span class="keyword">const</span> </span><br><span class="line"> {</span><br><span class="line"> Matrix ret;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</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<k;j++)</span><br><span class="line"> (ret[i+j]+=<span class="number">1l</span>l*a[i]*rhs[j]%P)%=P;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">2</span>*k<span class="number">-2</span>;i>=k;ret[i--]=<span class="number">0</span>) <span class="comment">// notice ret[i--]=0</span></span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=k;j++)</span><br><span class="line"> (ret[i-j]+=<span class="number">1l</span>l*ret[i]*f[j]%P)%=P;</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line"> }</span><br><span class="line">}res;</span><br><span class="line"></span><br><span class="line"><span class="function">Matrix <span class="title">ksm</span><span class="params">(Matrix a,<span class="keyword">int</span> b)</span> <span class="comment">// 严格来说,不是快速幂</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> Matrix ret;</span><br><span class="line"> ret[<span class="number">0</span>]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(;b;a=a*a,b>>=<span class="number">1</span>) <span class="keyword">if</span>(b&<span class="number">1</span>) ret=ret*a;</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></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<=k;i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&f[i]),f[i]=f[i]><span class="number">0</span>?f[i]:f[i]+P;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<k;i++) <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&h[i]),h[i]=h[i]><span class="number">0</span>?h[i]:h[i]+P;</span><br><span class="line"> <span class="keyword">if</span>(n<k) <span class="built_in">printf</span>(<span class="string">"%d\n"</span>,h[n]);</span><br><span class="line"> res[<span class="number">1</span>]=<span class="number">1</span>;ans=<span class="number">0</span>;</span><br><span class="line"> res=ksm(res,n);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<k;i++) ans=(ans+<span class="number">1l</span>l*res[i]*h[i]%P)%P;</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="meta">#<span class="meta-keyword">ifdef</span> LOCAL</span></span><br><span class="line"> system(<span class="string">"pause"</span>);</span><br><span class="line"> <span class="meta">#<span class="meta-keyword">endif</span></span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> 数学 </tag>
</tags>
</entry>
<entry>
<title>杜教筛初步</title>
<link href="/2018/06/23/%E6%9D%9C%E6%95%99%E7%AD%9B%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<url>/2018/06/23/%E6%9D%9C%E6%95%99%E7%AD%9B%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<p>之前学杜教筛的时候感觉没有学的很明白,现在重新学习一遍。</p><h1 id="杜教筛简介"><a href="#杜教筛简介" class="headerlink" title="杜教筛简介"></a>杜教筛简介</h1><p>何为杜教筛?<br>说直白一点就是在低于线性的时间内求出某个积性函数的前缀和。</p><p>假设现在我们有一个积性函数$f(i)$,设$S(i)=\sum\limits_{j=1}^{i} f(i)$。</p><p>我们要求$S(n)$,假设我们找到了另一个任意数论函数$g(i)$ 。</p><p>那么可以很轻松地得到如下的推导:</p><script type="math/tex; mode=display">\begin{align}\sum_{i=1}^n (f*g) (i) &= \sum _{i=1} ^{n} \sum _{d|i} g(d) f( \frac {i} {d } ) \\&=\sum _{d=1} ^{n} g(d) \sum _{d|i} ^{n} f ( \frac {i} {d} ) \\ &=\sum_{d=1} ^{n} g(d) \sum _{i=1} ^{ \lfloor \frac {n} {d} \rfloor } f(i) \\&=\sum _{d=1} ^{n} g(d) S( \lfloor \frac {n} {d} \rfloor)\end{align}</script><p>然后我们做进一步推导:</p><script type="math/tex; mode=display">\begin {align}&\begin {split}\sum _{i=1} ^{n} (f*g) (i) &= \sum _{d=1} ^{n} g(d) S( \lfloor \frac {n} {d} \rfloor) \\&= g(1)S(n) + \sum _{d=2} ^{n} g(d) S( \lfloor \frac {n} {d} \rfloor ) \\\end {split} \\&\therefore g(1)S(n) = \sum _{i=1} ^{n} (f*g) (i) -\sum _{d=2} ^{n} g(d) S( \lfloor \frac {n} {d} \rfloor )\end {align}</script><p>也就是说,如果我们能够找到一个积性函数$g$,并且我们能够快速计算$(f*g)$的前缀和,$g$的前缀和,那么我们的问题就可以用我们最后得到的那个式子进行计算,具体来说就是可以用数论分块,然后最后一项进行递归处理。</p><h1 id="例题"><a href="#例题" class="headerlink" title="例题"></a>例题</h1><h2 id="BZOJ-3944"><a href="#BZOJ-3944" class="headerlink" title="BZOJ 3944"></a>BZOJ 3944</h2><p><a href="https://www.lydsy.com/JudgeOnline/problem.php?id=3944" target="_blank" rel="noopener">Link</a></p><h3 id="题意"><a href="#题意" class="headerlink" title="题意"></a>题意</h3><p>求$\sum\limits<em>{i=1}^{n} \varphi(i)$和$\sum\limits</em>{i=1}^{n} \mu(i)$。</p><p>$n\leqslant 2^{31}-1$</p><h3 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h3><p>我们首先考虑$\sum\limits_{i=1}^{n} \varphi(i)$。</p><p>按照刚才那套理论,我们需要找到一个函数$g$,并且$(g*\varphi)$和$g$的前缀和均能够容易求出。</p><p>我们不难想到,$\varphi *I=id$,并且$id$和$1$的函数均可以很容易地求出。</p><p>所以不妨令$g$函数就是恒等函数$I$。</p><p>那么我们就有:</p><script type="math/tex; mode=display">\begin {align}S(n) &= \sum _{i=1} ^{n} i - \sum_{i=2} ^{n} S( \lfloor \frac {n} {i} \rfloor)\end {align}</script><p>然后就可以前半部分用公式,后半部分数论分块+递归。</p><p>我们再来考虑$\sum\limits_{i=1}^{n} \mu(i)$。</p><p>按照刚才那套理论,我们需要找到一个函数$g$,并且$(g*\mu)$和$g$的前缀和均能够容易求出。</p><p>我们不难想到$\mu *1=\varepsilon$。</p><p>那么我们不妨令$g$为恒等函数$I$。</p><p>于是我们带入得到:</p><script type="math/tex; mode=display">S(n) = 1-\sum _{i=2} ^{n} S( \lfloor \frac {n} {i} \rfloor)</script><p>直接数论分块+递归即可。</p><h2 id="洛谷P3768-简单的数学题"><a href="#洛谷P3768-简单的数学题" class="headerlink" title="洛谷P3768 简单的数学题"></a>洛谷P3768 简单的数学题</h2><p><a href="https://www.luogu.org/problemnew/show/P3768" target="_blank" rel="noopener">Link</a></p><h3 id="题意-1"><a href="#题意-1" class="headerlink" title="题意"></a>题意</h3><p>求$\sum\limits<em>{i=1} ^{n}\sum\limits\limits </em>{j=1} ^{n} ij*gcd(i,j)$</p><p>$n \leqslant 10^{10}$</p><h3 id="题解-1"><a href="#题解-1" class="headerlink" title="题解"></a>题解</h3><p>我们首先对原式进行反演。</p><script type="math/tex; mode=display">\begin {align}&\begin {split}Ans &= \sum _{i=1} ^{n} \sum _{j=1} ^{n} ij*gcd(i,j) \\&= \sum _{i=1} ^{n} \sum _{j=1} ^{n} ij \sum _{d|i,d|j} \varphi(d) \\&= \sum _{d=1} ^{n} \varphi(d)\sum _{i|d} ^{n} \sum _{j|d} ^{n} ij \\&= \sum _{d=1} ^{n} \varphi(d) d^2 \sum_{i=1} ^{\lfloor \frac {n} {d} \rfloor} \sum _{j=1} ^{ \lfloor \frac {n} {d} \rfloor} ij\\&= \sum _{d=1} ^{n} \varphi(d) d^2 (\sum_{i=1} ^{\lfloor \frac {n} {d} \rfloor} i)^2 \\&= \sum _{d=1} ^{n} \varphi(d) d^2 \sum_{i=1} ^{\lfloor \frac {n} {d} \rfloor} i ^3\end {split} \\\end {align}</script><p>现在的问题就是快速求出$\varphi(d)d^2$的前缀和。</p><p>我们设$f(i)=\varphi(i)*i^2$,$S(i)=\sum\limits_{j=1}^{i} f(j)$。</p><p>现在我们要找到函数$g$,使得我们能够快速计算$(f*g)$的前缀和,$g$的前缀和。</p><p>也就是说,我们需要能够快速求以下这个式子:</p><script type="math/tex; mode=display">\begin {align}&\begin {split}Ans &= \sum _{i=1} ^{n} \sum _{d|i} f(d)*g(\frac{i}{d}) \\&= \sum _{i=1} ^{n} \sum _{d|i} \varphi(d)d^2*g(\frac{i}{d})\end{split} \\&\text{我们不妨令}g(i)=i^2 \\&\begin {split}Ans &=\sum _{i=1} ^{n} \sum _{d|i} \varphi(d) i^2 \\&=\sum _{i=1} ^{n}i^3\end {split}\end{align}</script><p>所以我们只需要使$g(i)=i^2$,然后继续使用刚才的刚才的方法就可以完成此题。</p>]]></content>
<categories>
<category> 学习笔记 </category>
</categories>
<tags>
<tag> 数学 </tag>
<tag> 莫比乌斯反演 </tag>
</tags>
</entry>
<entry>
<title>[51NOD 1594] Gcd and Phi</title>
<link href="/2018/05/17/51NOD-1594-Gcd-and-Phi/"/>
<url>/2018/05/17/51NOD-1594-Gcd-and-Phi/</url>
<content type="html"><![CDATA[<p>题目大意:给定n,求$F(n) = \sum<em>{i=1}^{n} \sum</em>{j=1}^{n} \varphi( \gcd(\varphi(i),\varphi(j)))$ ,多组数据。</p><p>$n \leqslant 10^5 ,T \leqslant 5$</p><script type="math/tex; mode=display">F(n) = \sum_{i=1}^{n} \sum_{j=1}^{n} \varphi( \gcd(\varphi(i),\varphi(j)))</script><p>不妨设$p[x]=\sum\limits_{i=1}^{n} [\varphi(i)==x]$</p><p>不妨枚举$\varphi$的取值,易作如下变形</p><script type="math/tex; mode=display">\begin{align}F(n) &= \sum_{i=1}^{n} \sum_{j=1}^{n} \varphi( \gcd(\varphi(i),\varphi(j)) ) \\F(n) &= \sum_{i=1}^{n} \sum_{j=1}^{n} \varphi(\gcd(i,j)) \times p[i] \times p[j] \\F(n) &= \sum_{i=1}^{n} \sum_{j=1}^{n} p[i] \times p[j] \times \sum_{d|i,d|j}\varphi(d) \times \varepsilon(\gcd(\frac{i}{d},\frac{j}{d})) \\F(n) &=\sum_{d=1}^{n} \sum_{i=1}^{\lfloor{\frac{n}{d}}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{d}\rfloor} \varphi(d) \times p[i d] \times p[j d] \times \varepsilon(\gcd(i,j)) \\F(n) &=\sum_{d=1}^{n} \sum_{i=1}^{\lfloor{\frac{n}{d}}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{d}\rfloor} \varphi(d) \times p[i d] \times p[j d] \times \sum_{d'|i,d'|j} \mu(d') \\F(n) &=\sum_{d=1}^{n} \sum_{d'=1} ^{\lfloor\frac{n}{d}\rfloor}\sum_{i=1}^{\lfloor{\frac{n}{dd'}}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{dd'}\rfloor} \mu(d') \times\varphi(d) \times p[i d d'] \times p[j d d'] \\F(n) &=\sum_{d=1}^{n} \varphi(d) \sum_{d'=1} ^{\lfloor\frac{n}{d}\rfloor} \mu(d') \sum_{i=1}^{\lfloor{\frac{n}{dd'}}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{dd'}\rfloor} p[i d d'] \times p[j d d']\end{align}</script><p>不妨设$G(x)=\sum\limits<em>{i=1}^{\lfloor \frac{n}{x} \rfloor } \sum\limits</em>{j=1}^{\lfloor \frac{n}{x} \rfloor} p[ix] \times p[jx]$</p><p>显然,</p><script type="math/tex; mode=display">\begin{align}G(x) &= \sum\limits_{i=1}^{\lfloor \frac{n}{x} \rfloor } \sum\limits_{j=1}^{\lfloor \frac{n}{x} \rfloor} p[ix] \times p[jx] \\G(x) &= \sum\limits_{i=1}^{\lfloor \frac{n}{x} \rfloor } p[ix] \sum\limits_{j=1}^{\lfloor \frac{n}{x} \rfloor} p[jx] \\G(x) &=(\sum_{i=1}^{\lfloor \frac{n}{x}\rfloor} p[ix])^2\end{align}</script><p>这个东西可以$\mathcal{O}(n \ log_2 n)$求。</p><p>我们看看$F(n)$变成了什么</p><script type="math/tex; mode=display">\begin {align}F(n) &=\sum_{d=1}^{n} \varphi(d) \sum_{d'=1} ^{\lfloor\frac{n}{d}\rfloor} \mu(d') \sum_{i=1}^{\lfloor{\frac{n}{dd'}}\rfloor} \sum_{j=1}^{\lfloor\frac{n}{dd'}\rfloor} p[i d d'] \times p[j d d']\\F(n) &= \sum_{d=1}^{n} \varphi(d) \sum_{d'=1} ^{\lfloor\frac{n}{d}\rfloor} \mu(d') \times G(dd')\end {align}</script><p>这个东西也可以$\mathcal{O}(n \log_2 n)$求。</p><p>好,做完了。</p><p>代码如下<br><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"><cstdlib></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cctype></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stack></span></span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN=<span class="number">2E6</span>+<span class="number">10</span>;</span><br><span class="line"><span class="keyword">int</span> phi[MAXN],mu[MAXN],n,pri[MAXN],tot,p[MAXN],T;</span><br><span class="line">ll f[MAXN],ans;</span><br><span class="line"><span class="keyword">bool</span> vis[MAXN];</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="function"></span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&n);tot=<span class="number">0</span>;</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">memset</span>(f,<span class="number">0</span>,<span class="keyword">sizeof</span> f);</span><br><span class="line"> <span class="built_in">memset</span>(p,<span class="number">0</span>,<span class="keyword">sizeof</span> p);</span><br><span class="line"> phi[<span class="number">1</span>]=mu[<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<=n;i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(!vis[i]) pri[++tot]=i,mu[i]=<span class="number">-1</span>,phi[i]=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<=tot&&pri[j]*i<=n;j++)</span><br><span class="line"> {</span><br><span class="line"> vis[pri[j]*i]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(i%pri[j]==<span class="number">0</span>) {mu[i*pri[j]]=<span class="number">0</span>;phi[i*pri[j]]=phi[i]*pri[j];<span class="keyword">break</span>;}</span><br><span class="line"> <span class="keyword">else</span> mu[i*pri[j]]=-mu[i],phi[i*pri[j]]=phi[i]*(pri[j]<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) ++p[phi[i]];</span><br><span class="line"> 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">for</span>(<span class="keyword">int</span> j=i;j<=n;j+=i)</span><br><span class="line"> f[i]+=p[j];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) f[i]=f[i]*f[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="keyword">if</span>(mu[i])</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;i*j<=n;j++)</span><br><span class="line"> ans+=mu[i]*f[i*j]*phi[j];</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,ans);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&T);</span><br><span class="line"> <span class="keyword">while</span>(T--) solve();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></p>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 数学 </tag>
<tag> 莫比乌斯反演 </tag>
</tags>
</entry>
<entry>
<title>APIO2018 游记</title>
<link href="/2018/05/13/APIO2018-%E6%B8%B8%E8%AE%B0/"/>
<url>/2018/05/13/APIO2018-%E6%B8%B8%E8%AE%B0/</url>
<content type="html"><![CDATA[<p>这篇游记是回石家庄的火车上写的,<del>所以可能有口胡</del></p><h1 id="Day0-2018-5-10"><a href="#Day0-2018-5-10" class="headerlink" title="Day0 2018.5.10"></a>Day0 2018.5.10</h1><p>从石家庄坐火车去北京,还是一样的火车站,还是一样的地铁站。</p><p><del>话说前一天竟然将电源落在机房了,不爽</del></p><p>到宾馆的时候大概是11点左右,但是那时候房间都没有腾出来,<del>不爽</del>。</p><p>所以闭<del>(包)</del>队先带我们去吃了个饭<del>(话说还真有酱爆鸡丁这种操作)</del>。</p><p>吃完,回酒店,竟然还没好,差评。</p><p>没办法,只好先去试机。</p><p>学校好远。。。</p><p>先敲了个后缀自动机,略微调了一会,还好。</p><p>又写了写后缀数组和$NTT$,基本上一遍过,感觉$OK$。</p><p>话说ztb和czy都调了不短的时间,23333。</p><p><del>临走时顺便白嫖了点水</del></p><p>房间终于好了,不愧是五星级酒店,<del>爽到</del></p><h1 id="Day1-2018-5-11"><a href="#Day1-2018-5-11" class="headerlink" title="Day1 2018.5.11"></a>Day1 2018.5.11</h1><p><del>上午一开始先来了张刺</del><del>激人心的图片</del>,如下</p><img src="/2018/05/13/APIO2018-游记/1.jpg"><p>哇,竟然有秦岳,<del>害怕</del></p><p>首先先讲了讲折纸与信息技术,感觉很懵逼。</p><p>接下来是秦岳的图片拼接算法和<del>(游戏)</del>人工智能。</p><p>感觉挺有意思的。</p><p><del>话说首师大附中的午饭还不错</del></p><p>下午首先讲的是二分,竟然有HEOI2016原题,感觉听懂了不少。</p><p>讲课的时候竟然还能开弹幕,学到了。<del>(性感AP,在线IO)</del></p><p>然后是hht的玄学一般图匹配。</p><p>晚上在宾馆摸着。</p><p>明天考试好虚啊。</p><h1 id="Day2-2018-5-12"><a href="#Day2-2018-5-12" class="headerlink" title="Day2 2018.5.12"></a>Day2 2018.5.12</h1><p>今天考试。</p><p>考成mengbier。</p><p>没了。</p><h1 id="Day-3-2018-5-13"><a href="#Day-3-2018-5-13" class="headerlink" title="Day 3 2018.5.13"></a>Day 3 2018.5.13</h1><p>今天是北大的人来讲课啊。。。</p><p>上午讲了些什么杜教筛,洲阁筛和$Min_25$筛和比较高端的数论知识。</p><p>下午去80中,讲了些后缀自动机。<del>(话说你画我猜还真是好玩)</del></p><p>晚上坐火车回石家庄。</p><p>2018.6.22 @ 高铁</p>]]></content>
<categories>
<category> 游记 </category>
</categories>
<tags>
<tag> 游记 </tag>
</tags>
</entry>
<entry>
<title>[九省联考2018]秘密袭击CoaT</title>
<link href="/2018/05/04/%E4%B9%9D%E7%9C%81%E8%81%94%E8%80%832018-%E7%A7%98%E5%AF%86%E8%A2%AD%E5%87%BBCoaT/"/>
<url>/2018/05/04/%E4%B9%9D%E7%9C%81%E8%81%94%E8%80%832018-%E7%A7%98%E5%AF%86%E8%A2%AD%E5%87%BBCoaT/</url>
<content type="html"><![CDATA[<p>这篇题解写的是<strong>官方正解</strong>。</p><p>正解需要以下知识</p><ul><li>整体DP</li><li>多项式初步</li><li>拉格朗日插值法 <del>(可以在<a href="https://Zhang-RQ.github.io/2018/05/04/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E6%8F%92%E5%80%BC%E6%B3%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">这里</a>学)</del></li><li>生成函数</li><li>线段树合并</li></ul><p>题目大意:</p><p> 给一颗有$N$个点的树,点权在$1 \sim W$之间,求树的每一个联通块的第$K$大点权之和。</p><p>看到这个题时,我的心里是懵逼的。</p><p>我们首先开始考虑转化题目。</p><script type="math/tex; mode=display">\begin{align}Ans &= \sum_{S \in T} k_{th} \ \ of \ \ S \tag{1} \\&= \sum_{i=1}^{W} i \times \sum_{S \in T} [k_{th}\ of \ S==i] \tag{2}\\&=\sum_{i=1}^{W} \sum_{S \in T} {[k_{th} \ of \ S \geqslant i]} \tag{3}\\&=\sum_{i=1}^{W} \sum_{S \in T} {[cnt[i] \geqslant k]} \tag{4}\end{align}</script><p>$(1)$到$(2)$的过程是枚举每个权值的贡献。</p><p>$(2)$到$(3)$的过程比较难理解,我们直接考虑从每个$i$在公式$(2)$中会被算多少次,显然是$i$次。</p><p>那在公式$(3)$中也是会被算$i$次。</p><p>$(3)$到$(4)$的过程就比较显然了,这里不再赘述。</p><p>那么到现在,问题就变得比较显然了:</p><p>枚举权值$v$,求树上权值$v$出现次数超过$k$的联通块个数。</p><p>我们设计一个DP。</p><p>$f[i][j][k]$表示以$i$为根的子树中,权值大于等于$j$的权值出现为$k$次的方案数。</p><p>转移显然</p><script type="math/tex; mode=display">\begin{align}f[i][j][k] &= \prod_{v \in son[i]} f[v][j][k'] \ \ \ \ (d[i]<j,\sum k'=k)\\f[i][j][k] &= \prod_{v \in son[i]} f[v][j][k'] \ \ \ \ (d[i] \geqslant j,\sum k'=k-1)\end{align}</script><p>最后答案就是$\sum\limits<em>{k’=1}^{k}\sum\limits</em>{j=1}^{W}\sum\limits_{i=1}^{N} f[i][j][k’]$</p><p>复杂度$\mathcal{O}(N^2*k)$,据说有人大力过了。</p><p>我们考虑优化这个转移,不难发现,这个DP其实是背包的一种,而转移就是背包的合并。</p><p>那我们不妨直接考虑生成函数。</p><p>设$F[i][j]$表示以$i$为根的子树中,权值大于等于$j$的权值的生成函数。</p><p>则$F[i][j]=\sum\limits_{k=0}^{n} f[i][j][k] \times x^k$,这是一个$N$次多项式。</p><p>但是最后我们要求的是整棵树的所有$F[i][j]$之和,所以我们不妨再设一个$G[i][j]$。</p><p>$G[i][j]=\sum\limits_{x \in subtree(i)}F[x][j]$</p><p>$F[i][j]$在转移时是多项式卷积,还是很慢,$G[i][j]$在转移时只要维护一下就行了。</p><p>所以我们考虑将它转换为$N+1$个点值,这样的话转移时就是普通乘法了。</p><p>我们就令$x=1 \sim N+1$,然后将所有$G[i][j]$在$x$时的值都求出来,最后进行拉格朗日插值法将原始的多项式差出来就行了,可具体怎么实现呢?</p><p>我们首先在最外层枚举$x \in [1,N+1]$,然后每次进行一次$DFS$,但具体如何进行转移呢?</p><p>我们不难发现,$F[i][j] \leftarrow F[son[i]][j]$转移过程中其实就是$[j]$的对应位置相乘。</p><p>所以我们可以使用整体$DP$的思想在每个点上都维护一颗线段树,然后在转移时进行线段树合并就可以了。</p><p>正解差不多就是这个意思。</p><p>具体合并方法如下:</p><p>初始化:</p><script type="math/tex; mode=display">\begin{align}F[i][j] &= x \ \ \ \ (d[i] \geqslant j)\\F[i][j] &= 1 \ \ \ \ (d[i] < j) \end{align}</script><p>转移时: $F[i][j] \times =(F[son[i]][j]+1) , G[i][j]+=G[son[i]][j]$</p><p>最后,$G[i][j]+=F[i][j]$。</p><p>我们可以将$F[son[i]][j]+1$的操作放在$DFS$ son[i]后进行。</p><p>可是你说了这么多,线段树到底应该怎么写?</p><p>我们设变换$(a,b,c,d)$可以使$(f,g)$变换为$(a \times f+b,c \times f+d+g)$</p><p>然后每个线段树维护一个变换即可。</p><p>变换结合的话手推一下即可。</p><p>注意:变换在普遍情况下没有交换律,只有结合律。</p><p>剩下的实现方法详见代码。</p><p>注意以下坑点:</p><ul><li>模数是64123,做乘法时要用unsigned int。</li><li>unsigned int 取模时模数必须是unsigned类型。</li><li>初始化变换时应该是$(1,0,0,0)$</li></ul><p>代码:</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br></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"><cstdlib></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cctype></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cassert></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="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">int</span> uint;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">const</span> uint P=<span class="number">64123</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN=<span class="number">1700</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXM=<span class="number">5000</span>;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> __<span class="title">edge</span>{</span></span><br><span class="line"> <span class="keyword">int</span> nxt,v;</span><br><span class="line">}Edge[MAXM];</span><br><span class="line"><span class="keyword">int</span> head[MAXN],cnt_e,rt[MAXN],stk[MAXN<<<span class="number">6</span>],top,cnt,d[MAXN],n,k,w,u,v,ans[MAXN],f[MAXN],tmp[MAXN];</span><br><span class="line"><span class="keyword">int</span> inv[P+<span class="number">10</span>];</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <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>{Edge[++cnt_e].v=v;Edge[cnt_e].nxt=head[u];head[u]=cnt_e;}</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">data</span>{</span></span><br><span class="line"> uint a,b,c,d;</span><br><span class="line"> <span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">clear</span><span class="params">()</span></span>{a=<span class="number">1</span>;b=c=d=<span class="number">0</span>;}</span><br><span class="line"> inline data(uint _a=1,uint _b=0,uint _c=0,uint _d=0):a(_a),b(_b),c(_c),d(_d){}</span><br><span class="line"> <span class="keyword">inline</span> data <span class="keyword">operator</span> * (<span class="keyword">const</span> data &rhs) <span class="keyword">const</span> {<span class="keyword">return</span> data(a*rhs.a%P,(rhs.b+b*rhs.a%P)%P,(a*rhs.c%P+c)%P,(b*rhs.c%P+d+rhs.d)%P);}</span><br><span class="line"> <span class="keyword">inline</span> data <span class="keyword">operator</span> *= (<span class="keyword">const</span> data &rhs) {<span class="keyword">return</span> (*<span class="keyword">this</span>)=(*<span class="keyword">this</span>)*rhs;}</span><br><span class="line">};</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">node</span>{</span></span><br><span class="line"> <span class="keyword">int</span> ls,rs;</span><br><span class="line"> data val;</span><br><span class="line"> node(){val.a=<span class="number">1</span>;val.b=val.c=val.d=ls=rs=<span class="number">0</span>;}</span><br><span class="line"> <span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">clear</span><span class="params">()</span></span>{val.a=<span class="number">1</span>;val.b=val.c=val.d=ls=rs=<span class="number">0</span>;}</span><br><span class="line">}t[MAXN<<<span class="number">6</span>];</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">int</span> <span class="title">newnode</span><span class="params">()</span> </span>{<span class="keyword">if</span>(top) <span class="keyword">return</span> stk[top--];<span class="keyword">else</span> <span class="keyword">return</span> ++cnt;}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">delnode</span><span class="params">(<span class="keyword">int</span> &x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(!x) <span class="keyword">return</span>;</span><br><span class="line"> delnode(t[x].ls);delnode(t[x].rs);</span><br><span class="line"> stk[++top]=x;t[x].clear();x=<span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">pushdown</span><span class="params">(<span class="keyword">const</span> <span class="keyword">int</span> &x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(!t[x].ls) t[x].ls=newnode();</span><br><span class="line"> <span class="keyword">if</span>(!t[x].rs) t[x].rs=newnode();</span><br><span class="line"> t[t[x].ls].val*=t[x].val;</span><br><span class="line"> t[t[x].rs].val*=t[x].val;</span><br><span class="line"> t[x].val.clear();</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">change</span><span class="params">(<span class="keyword">int</span> &x,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> cl,<span class="keyword">int</span> cr,data val)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(!x) x=newnode();</span><br><span class="line"> <span class="keyword">if</span>(cl<=l&&r<=cr) {t[x].val*=val;<span class="keyword">return</span>;}</span><br><span class="line"> <span class="keyword">int</span> mid=(l+r)>><span class="number">1</span>;pushdown(x);</span><br><span class="line"> <span class="keyword">if</span>(cl<=mid) change(t[x].ls,l,mid,cl,cr,val);</span><br><span class="line"> <span class="keyword">if</span>(cr>mid) change(t[x].rs,mid+<span class="number">1</span>,r,cl,cr,val);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">merge</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="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(!x||!y) <span class="keyword">return</span> x|y;</span><br><span class="line"> <span class="keyword">if</span>(!t[x].ls&&!t[x].rs) swap(x,y);</span><br><span class="line"> <span class="keyword">if</span>(!t[y].ls&&!t[y].rs)</span><br><span class="line"> {</span><br><span class="line"> t[x].val*=data(t[y].val.b,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>);</span><br><span class="line"> t[x].val*=data(<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>,t[y].val.d);</span><br><span class="line"> <span class="keyword">return</span> x;</span><br><span class="line"> }</span><br><span class="line"> pushdown(x);pushdown(y);</span><br><span class="line"> t[x].ls=merge(t[x].ls,t[y].ls);</span><br><span class="line"> t[x].rs=merge(t[x].rs,t[y].rs);</span><br><span class="line"> <span class="keyword">return</span> x;</span><br><span class="line">}</span><br><span class="line"><span class="function">uint <span class="title">query</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(l==r) <span class="keyword">return</span> t[x].val.d;</span><br><span class="line"> <span class="keyword">int</span> mid=(l+r)>><span class="number">1</span>;</span><br><span class="line"> uint ret=<span class="number">0</span>;</span><br><span class="line"> pushdown(x);</span><br><span class="line"> ret=query(t[x].ls,l,mid);</span><br><span class="line"> (ret+=query(t[x].rs,mid+<span class="number">1</span>,r))%=P;</span><br><span class="line"> <span class="keyword">return</span> ret;</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 class="keyword">int</span> fa,<span class="keyword">int</span> k0)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> change(rt[x],<span class="number">1</span>,w,<span class="number">1</span>,w,data(<span class="number">0</span>,<span class="number">1</span>,<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=head[x];i;i=Edge[i].nxt)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> v=Edge[i].v;</span><br><span class="line"> <span class="keyword">if</span>(v==fa) <span class="keyword">continue</span>;</span><br><span class="line"> dfs(v,x,k0);</span><br><span class="line"> merge(rt[x],rt[v]);</span><br><span class="line"> delnode(rt[v]);</span><br><span class="line"> }</span><br><span class="line"> change(rt[x],<span class="number">1</span>,w,<span class="number">1</span>,d[x],data(k0,<span class="number">0</span>,<span class="number">0</span>,<span class="number">0</span>));</span><br><span class="line"> change(rt[x],<span class="number">1</span>,w,<span class="number">1</span>,w,data(<span class="number">1</span>,<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>));</span><br><span class="line"> change(rt[x],<span class="number">1</span>,w,<span class="number">1</span>,w,data(<span class="number">1</span>,<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>));</span><br><span class="line">}</span><br><span class="line"><span class="function">uint <span class="title">Lagrange_interpolation</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> uint ret=<span class="number">0</span>;</span><br><span class="line"> <span class="built_in">memset</span>(f,<span class="number">0</span>,<span class="keyword">sizeof</span> f);f[<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<=n+<span class="number">1</span>;i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=n+<span class="number">1</span>;j>=<span class="number">1</span>;j--)</span><br><span class="line"> f[j]=f[j]*(P-i)%P,f[j]=(f[j]+f[j<span class="number">-1</span>])%P;</span><br><span class="line"> f[<span class="number">0</span>]=f[<span class="number">0</span>]*(P-i)%P;</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+<span class="number">1</span>;i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">memcpy</span>(tmp,f,<span class="keyword">sizeof</span>(uint)*(n+<span class="number">1</span>));</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">0</span>;j<=n;j++) <span class="comment">//divide by (x-i)</span></span><br><span class="line"> tmp[j]=P-tmp[j]*inv[i]%P,tmp[j+<span class="number">1</span>]=(tmp[j+<span class="number">1</span>]-tmp[j]+P)%P;</span><br><span class="line"> uint tans=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=k;j<=n;j++) tans=(tans+tmp[j])%P;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=n+<span class="number">1</span>;j++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(i==j) <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">if</span>(j<i) tans=tans*inv[i-j]%P;</span><br><span class="line"> <span class="keyword">else</span> tans=tans*(P-inv[j-i])%P;</span><br><span class="line"> }</span><br><span class="line"> ret=(ret+tans*ans[i]%P)%P;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> ret;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%d"</span>,&n,&k,&w);</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>,&d[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 class="built_in">scanf</span>(<span class="string">"%d%d"</span>,&u,&v),add(u,v),add(v,u);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n+<span class="number">1</span>;i++)</span><br><span class="line"> {</span><br><span class="line"> dfs(<span class="number">1</span>,<span class="number">0</span>,i);</span><br><span class="line"> ans[i]=query(rt[<span class="number">1</span>],<span class="number">1</span>,w);</span><br><span class="line"> delnode(rt[<span class="number">1</span>]);</span><br><span class="line"> }</span><br><span class="line"> 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<P;i++)</span><br><span class="line"> inv[i]=(P-(P/i)*inv[P%i]%P)%P,assert(inv[i]><span class="number">0</span>);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%u\n"</span>,Lagrange_interpolation());</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 多项式 </tag>
<tag> 拉格朗日插值法 </tag>
<tag> 整体DP </tag>
<tag> 线段树 </tag>
<tag> 生成函数 </tag>
</tags>
</entry>
<entry>
<title>拉格朗日插值法学习笔记</title>
<link href="/2018/05/04/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E6%8F%92%E5%80%BC%E6%B3%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<url>/2018/05/04/%E6%8B%89%E6%A0%BC%E6%9C%97%E6%97%A5%E6%8F%92%E5%80%BC%E6%B3%95%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<p>拉格朗日插值法是个好东西。</p><p>它能干什么呢?</p><p>比如说你有一个未知的$N$次多项式,并且你有$N+1$ 个点值,那么你可以$\mathcal{O}(N^2)$地求出它的系数。</p><p><del>(高斯消元就不说了)</del></p><p>我们考虑怎么做,</p><p>先考虑一个问题,如果你有一个未知的$N$次多项式并且你有$N+1$ 个点值,那么再给你一个$x$,你能不能求出它所对应的函数值。</p><p><del>(编不下去了)</del>直接看公式</p><script type="math/tex; mode=display">f(x_0)=\sum_{i=1}^{n+1}\frac{\prod\limits_{i!=j}(x_0-x_j)}{\prod\limits_{i!=j}(x_i-x_j)} \times f(x_i)</script><p>考虑这个式子的正确性,我们带入已知的点值,比如说$x_3$,那么只有当$i=3$时,前面的分式值为一,其余时候,前面的分式值为$0$。所以这个式子是对的。<del>(记住就好了)</del></p><p>那这只是带一个值进去的时候,我如果想求多项式怎么办?</p><script type="math/tex; mode=display">f(x)=\sum_{i=1}^{n+1}\frac{\prod\limits_{i!=j}(x-x_j)}{\prod\limits_{i!=j}(x_i-x_j)} \times f(x_i)</script><p>这就是我们求多项式时的公式,那我们应该怎么算?</p><p>不难发现,真正难算的地方时分子部分,分母部分是一个实数。</p><p>那我们应该怎么处理?</p><p>不难发现,对于所有$i$,分子的形式很相像,那我们不妨先算出$\prod\limits_{i=1}^{n}(x-x_i)$,然后再除一下就行了。</p><p>暴力计算显然是$\mathcal{O}(N^3)$的。</p><p>So?</p><p>假设我们已经求完了前$i-1$项(记为$f’(x)$),现在要求第$i$项,那我们应该怎么做?</p><p>我们要算$f’(x) \times (x-x_i)$。</p><script type="math/tex; mode=display">\begin{align}Ans & =f'(x) \times (x-x_i) \\& =f'(x) \times x-f'(x) \times x_i \\\end{align}</script><p>我们不难发现,答案是先将自己乘$-x_i$,然后将自己加到下一位。</p><p>我们就可以从高向低枚举次数,然后做转移即可。</p><p>那除法也一样,逆序操作即可。</p><p>那么我们就算出来了这个多项式的各个系数。</p><p>总复杂度$\mathcal{O}(N^2)$</p>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> 数学 </tag>
<tag> 拉格朗日插值法 </tag>
</tags>
</entry>
<entry>
<title>线性基学习笔记</title>
<link href="/2018/03/17/%E7%BA%BF%E6%80%A7%E5%9F%BA%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"/>
<url>/2018/03/17/%E7%BA%BF%E6%80%A7%E5%9F%BA%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/</url>
<content type="html"><![CDATA[<h3 id="预备知识"><a href="#预备知识" class="headerlink" title="预备知识"></a>预备知识</h3><h5 id="基"><a href="#基" class="headerlink" title="基"></a>基</h5><p> <strong>基</strong>是线性代数中的一个概念,它是描述、刻画向量空间的基本工具。而在OI题目中,线性基描述的向量空间一般是异或空间。</p><h5 id="向量空间"><a href="#向量空间" class="headerlink" title="向量空间"></a>向量空间</h5><p> 定义$(F,V,+,\cdot)$为<strong>向量空间</strong>,其中$F$为域,$V$为集合,$V$中的元素称为向量,$+$为<strong>向量</strong>加法,$\cdot$为<strong>标量乘法</strong>。</p><h5 id="线性无关"><a href="#线性无关" class="headerlink" title="线性无关"></a>线性无关</h5><p> 对于向量空间中 $V$上 $n $个元素的向量组$ (\mathbf{v}<em>1, \ldots, \mathbf{v}_n)$,若存在不全为 $0$ 的数 $a_i \in F$,满$a</em>{1}\mathbf {v} <em>{1}+a</em>{2}\mathbf {v} <em>{2}+\ldots +a</em>{n}\mathbf {v} _{n} = 0$则称这 $n$个向量<strong>线性相关</strong>,否则称为<strong>线性无关</strong>。</p><h5 id="线性组合"><a href="#线性组合" class="headerlink" title="线性组合"></a>线性组合</h5><p> 对于向量空间中 $V$ 上 $n$ 个元素的向量组 $(\mathbf{v}_1, \ldots, \mathbf{v}_n)$,其<strong>线性组合</strong>是如下形式的向量</p><p> $a<em>{1}\mathbf{v}</em>{1} + a<em>{2}\mathbf {v} </em>{2}+\ldots +a<em>{n}\mathbf {v} </em>{n}$其中 $a_1, \ldots, a_n \in F$a。一组向量线性无关$ \Leftrightarrow $没有向量可用有限个其他向量的线性组合所表示</p><h5 id="张成"><a href="#张成" class="headerlink" title="张成"></a>张成</h5><p> 对于向量空间中 $V$ 上 $n$ 个元素的向量组$ (\mathbf{v}_1, \ldots, \mathbf{v}_n)$,其所有线性组合所构成的集合称为$ (\mathbf{v}_1, \ldots, \mathbf{v}_n)$的<strong>张成</strong>,记为$ \mathrm{span}(\mathbf{v}_1, \ldots, \mathbf{v}_n)$。</p><h5 id="基-1"><a href="#基-1" class="headerlink" title="基"></a>基</h5><p> 若向量空间 $V$ 中向量组 $\mathfrak {B}$ 既是线性无关的又可以张成 $V$,则称其为 $V $的<strong>基(basis)</strong>。</p><p> $\mathfrak {B}$ 中的元素称为基向量。如果基中元素个数有限,就称向量空间为有限维向量空间,将元素的个数称作向量空间的维数。</p><h6 id="性质"><a href="#性质" class="headerlink" title="性质"></a>性质</h6><p>设 $\mathfrak {B}$ 是向量空间 $V $的基。则$ \mathfrak {B}$具有以下性质:</p><ol><li>$V$ 是$ \mathfrak {B}$ 的极小生成集,就是说只有 $\mathfrak {B}$ 能张成 $V,而它的任何真子集都不张成全部的向量空间。</li><li>$\mathfrak {B}$ 是 $V$ 中线性无关向量的极大集合,就是说 $\mathfrak {B}$ 在 $V $中是线性无关集合,而且 $V$ 中没有其他线性无关集合包含它作为真子集。</li><li>$V $中所有的向量都可以按唯一的方式表达为$ \mathfrak {B}$中向量的线性组合。</li></ol><p>第三点尤其重要,感性的理解,基就是向量空间中的一个子集,它可以通过唯一的线性组合,来张成向量空间中所有的向量,这样就可以大大的缩小我们向量空间的大小。</p><h5 id="线性相关性引理"><a href="#线性相关性引理" class="headerlink" title="线性相关性引理"></a>线性相关性引理</h5><p>如果$ (\mathbf{v}_1, \ldots, \mathbf{v}_n)$在 $V$ 中是线性相关的,并且 $\mathbf{v}_1 \neq 0$,则有至少一个 $j \in {2, \ldots, m}$使得下列成立:</p><ol><li>$\mathbf{v}<em>j \in \mathrm{span}(\mathbf{v}_1, \ldots, \mathbf{v}</em>{j - 1})$;</li><li>如果从 $(\mathbf{v}_1, \ldots, \mathbf{v}_n)$ 去掉第$j $项,则剩余向量组的张成仍然等于$ \mathrm{span}(\mathbf{v}_1, \ldots, \mathbf{v_n})$。</li></ol><h3 id="线性基介绍-口胡"><a href="#线性基介绍-口胡" class="headerlink" title="线性基介绍(口胡)"></a>线性基介绍(口胡)</h3><p>线性基是维护了一个数集的某些信息的集合(?)。</p><p>它可以将原来大小为$\text{N}$的数集在只求$\text{Xor}$和时压缩为$64$。</p><p>换句话说,你原来的数集互相异或出来的数的集合等于线性基中的数互相异或出来的数。</p><p>( 还是很有用的东西。)</p><h3 id="线性基求法"><a href="#线性基求法" class="headerlink" title="线性基求法"></a>线性基求法</h3><p>我在网上看线性基求法时,看到了如下两种线性基求法:</p><ol><li><p>复杂度$O(64n)$</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></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<=n;i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">62</span>;~j;j--)</span><br><span class="line"> <span class="keyword">if</span>(a[i]>>j&<span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(b[j]) a[i]^=b[j];</span><br><span class="line"> <span class="keyword">else</span> {b[j]=a[i];<span class="keyword">break</span>;}</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>其中,$\text{a}$数组是原来的数集,$\text{b}$是线性基。</p><p>注意,这种求法求出的线性基是<strong>上三角矩阵</strong>。</p></li><li><p>复杂度$O(64^2n)$</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></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<=cnt;i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">62</span>;~j;j--)</span><br><span class="line"> <span class="keyword">if</span>(lop[i]>>j&<span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(b[j]) lop[i]^=b[j];</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> b[j]=lop[i];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=j<span class="number">-1</span>;k>=<span class="number">1</span>;k--) <span class="keyword">if</span>(b[k]&&b[j]>>k&<span class="number">1</span>) b[j]^=b[k];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=j+<span class="number">1</span>;k<=<span class="number">62</span>;k++) <span class="keyword">if</span>(b[k]>>j&<span class="number">1</span>) b[k]^=b[j];</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p></p><p>可以发现,这种求法只比上面的求法多了两句话:</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> k=j<span class="number">-1</span>;k>=<span class="number">1</span>;k--) <span class="keyword">if</span>(b[k]&&b[j]>>k&<span class="number">1</span>) b[j]^=b[k];</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> k=j+<span class="number">1</span>;k<=<span class="number">62</span>;k++) <span class="keyword">if</span>(b[k]>>j&<span class="number">1</span>) b[k]^=b[j];</span><br></pre></td></tr></table></figure><p>不难发现,这两句话是高斯消元的过程,这种线性基求法求出来的线性基是<strong>对角矩阵</strong>。</p></li></ol>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> 线性基 </tag>
</tags>
</entry>
<entry>
<title>BZOJ2115:[WC2011]Xor</title>
<link href="/2018/03/17/BZOJ2115-WC2011-Xor/"/>
<url>/2018/03/17/BZOJ2115-WC2011-Xor/</url>
<content type="html"><![CDATA[<h3 id="题目大意"><a href="#题目大意" class="headerlink" title="题目大意"></a>题目大意</h3><p>你有一张$\text{N}$个点$\text{M}$条边的无向图,每条边上都有权值,现在请你求出来一条路径,使得这条路径上所有边权的异或和最大。</p><h3 id="题解"><a href="#题解" class="headerlink" title="题解"></a>题解</h3><p><strong>前置技能:线性基</strong> (不会的戳这里<a href="https://zhang-rq.github.io/2018/03/17/%E7%BA%BF%E6%80%A7%E5%9F%BA%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/">线性基学习笔记</a>)</p><p>我们可以发现,这张图上会出现很多的环,而如果走一个环,就会<strong>只</strong>获得这个环的异或和。因为在非环路都走了两遍,所以我们就可以将所有环都求出来,然后随意找一条从$1$到$N$的路径,并使用线性基贪心地选,这样就可以选出最大的路径了。</p><figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="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"><cstdlib></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cctype></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><vector></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stack></span></span></span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN=<span class="number">1E5</span>+<span class="number">5</span>;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXM=<span class="number">2E5</span>+<span class="number">5</span>;</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> nxt,v;</span><br><span class="line"> ll w;</span><br><span class="line">}Edge[MAXM];</span><br><span class="line"><span class="keyword">int</span> n,m,u,v;</span><br><span class="line">ll w;</span><br><span class="line"><span class="keyword">int</span> head[MAXN],cnt_e,cnt;</span><br><span class="line">ll dis[MAXN],lop[MAXM],b[<span class="number">64</span>];</span><br><span class="line"><span class="keyword">bool</span> vis[MAXN];</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <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,ll w)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> Edge[++cnt_e].v=v;</span><br><span class="line"> Edge[cnt_e].nxt=head[u];</span><br><span class="line"> Edge[cnt_e].w=w;</span><br><span class="line"> head[u]=cnt_e;</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 class="keyword">int</span> fa)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> vis[x]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=head[x];i;i=Edge[i].nxt)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> v=Edge[i].v;</span><br><span class="line"> <span class="keyword">if</span>(v==fa) <span class="keyword">continue</span>;</span><br><span class="line"> <span class="keyword">if</span>(vis[v]) {lop[++cnt]=dis[x]^dis[v]^Edge[i].w;<span class="keyword">continue</span>;}</span><br><span class="line"> dis[v]=dis[x]^Edge[i].w;</span><br><span class="line"> dfs(v,x);</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">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=cnt;i++)</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">62</span>;~j;j--)</span><br><span class="line"> <span class="keyword">if</span>(lop[i]>>j&<span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(b[j]) lop[i]^=b[j];</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> b[j]=lop[i];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=j<span class="number">-1</span>;k>=<span class="number">1</span>;k--) <span class="keyword">if</span>(b[k]&&b[j]>>k&<span class="number">1</span>) b[j]^=b[k];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> k=j+<span class="number">1</span>;k<=<span class="number">62</span>;k++) <span class="keyword">if</span>(b[k]>>j&<span class="number">1</span>) b[k]^=b[j];</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="function">ll <span class="title">solve</span><span class="params">(ll s)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> ll ret=s;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">62</span>;~i;i--)</span><br><span class="line"> <span class="keyword">if</span>((ret^b[i])>ret)</span><br><span class="line"> ret^=b[i];</span><br><span class="line"> <span class="keyword">return</span> ret;</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="function"></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<=m;i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d%d%lld"</span>,&u,&v,&w);</span><br><span class="line"> add(u,v,w);add(v,u,w);</span><br><span class="line"> }</span><br><span class="line"> dfs(<span class="number">1</span>,<span class="number">0</span>);</span><br><span class="line"> build();</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld\n"</span>,solve(dis[n]));</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 线性基 </tag>
</tags>
</entry>
<entry>
<title>记一道数学作业</title>
<link href="/2018/02/03/%E8%AE%B0%E4%B8%80%E9%81%93%E6%95%B0%E5%AD%A6%E4%BD%9C%E4%B8%9A/"/>
<url>/2018/02/03/%E8%AE%B0%E4%B8%80%E9%81%93%E6%95%B0%E5%AD%A6%E4%BD%9C%E4%B8%9A/</url>
<content type="html"><![CDATA[<ol><li><p>题目描述</p><p> 求小于 $ 120 $ 且与 $ 120 $ 互质的正整数个数。</p></li><li><p>做法</p><ol><li><p>普通做法</p><p> 将 $ 120 $ 分解质因数,可发现 $ 120=2^{3}\times3\times5 $。</p><p> 设 $A=\left{x|(2|x)且x\le120\right}$,$ B=\left{x|(3|x)且x\le120\right} $,$ C=\left{x|(5|x)且x\le120\right} $。</p><p> 则 $ |A|=59 $ $ |B|=39 $</p><p> 则小于 $ 120 $ 的正整数中,与 $ 120 $ 不互质的个数为 $ | A \cup B \cup C | $ 。</p><p> 由容斥原理可知。。。<del>(略)</del></p></li><li><p>文艺做法</p><p> 由题意可知,要求 $ \varphi(120) $ 。</p><p> 将 $ 120 $ 分解质因数,$ 120=2^{3} \times 3 \times 5 $。</p><p> 所以 $ \varphi(120)=120 \times \left(1-\frac{1}{2}\right) \times \left(1-\frac{1}{3}\right) \times \left(1-\frac{1}{5}\right) $</p></li><li><p>智障做法</p><p> 由莫比乌斯反演,可知 $ \varphi= \mu \times id $</p><p> 所以 $ \varphi=\sum_{d|120}^{120} \mu(d) \times id(\frac{120}{d}) $</p><p> 带值,求出 $ \varphi(120) $</p></li><li><p>OI做法</p> <figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">init</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> phi[<span class="number">1</span>]=sum[<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<=siz;i++)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">if</span>(!vis[i])</span><br><span class="line"> {</span><br><span class="line"> prime[++vnum]=i;</span><br><span class="line"> phi[i]=i<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<=vnum&&prime[j]*i<=siz;j++)</span><br><span class="line"> {</span><br><span class="line"> vis[prime[j]*i]=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span>(!(i%prime[j]))</span><br><span class="line"> {</span><br><span class="line"> phi[prime[j]*i]=phi[i]*prime[j];</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> phi[prime[j]*i]=phi[i]*phi[prime[j]];</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<=siz;i++)</span><br><span class="line"> (sum[i]=sum[i<span class="number">-1</span>]+phi[i])%=P;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol></li></ol>]]></content>
<categories>
<category> 杂谈 </category>
</categories>
<tags>
<tag> 迷 </tag>
<tag> 皮 </tag>
</tags>
</entry>
<entry>
<title>hihoCoder后缀自动机五题</title>
<link href="/2018/01/30/hihoCoder%E5%90%8E%E7%BC%80%E8%87%AA%E5%8A%A8%E6%9C%BA%E4%BA%94%E9%A2%98/"/>
<url>/2018/01/30/hihoCoder%E5%90%8E%E7%BC%80%E8%87%AA%E5%8A%A8%E6%9C%BA%E4%BA%94%E9%A2%98/</url>
<content type="html"><![CDATA[<h2 id="重复旋律5"><a href="#重复旋律5" class="headerlink" title="重复旋律5"></a>重复旋律5</h2><ol><li><p>链接</p><p> <a href="http://hihocoder.com/problemset/problem/1445" target="_blank" rel="noopener">后缀自动机二·重复旋律5</a></p></li><li><p>题意</p><p> 给定一个串,求这个串的本质不同的子串个数。</p></li><li><p>题解</p><ol><li><p>后缀数组</p><p>答案就是 $ \sum_{i=1}^{n} n-sa[i]-height[i]+1 $</p></li><li><p>后缀自动机</p><p>题目所求即 $ \sum_{i=1}^{cnt} siz[i] $</p><p>按照逆拓扑序递推一遍即可。</p></li></ol></li><li><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><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">calc</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> mxval=<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<=cnt;i++)</span><br><span class="line"> sum[mx[i]]++,mxval=max(mxval,mx[i]);</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=mxval;i++)</span><br><span class="line"> sum[i]+=sum[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<=cnt;i++)</span><br><span class="line"> tp[sum[mx[i]]--]=i;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=cnt;i>=<span class="number">1</span>;i--)</span><br><span class="line"> {</span><br><span class="line"> siz[par[tp[i]]]+=siz[tp[i]];</span><br><span class="line"> ans[mx[tp[i]]]=max(ans[mx[tp[i]]],siz[tp[i]]);</span><br><span class="line"> }</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"> ans[i]=max(ans[i],ans[i+<span class="number">1</span>]);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol><h3 id="未完待补"><a href="#未完待补" class="headerlink" title="(未完待补)"></a>(未完待补)</h3>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 后缀数组 </tag>
</tags>
</entry>
<entry>
<title>hihoCoder后缀数组四题</title>
<link href="/2018/01/30/hihoCoder%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84%E5%9B%9B%E9%A2%98/"/>
<url>/2018/01/30/hihoCoder%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84%E5%9B%9B%E9%A2%98/</url>
<content type="html"><![CDATA[<h2 id="重复旋律一"><a href="#重复旋律一" class="headerlink" title="重复旋律一"></a>重复旋律一</h2><ol><li><p>链接</p><p><a href="http://hihocoder.com/problemset/problem/1403" target="_blank" rel="noopener">后缀数组一·重复旋律</a></p></li><li><p>题意</p><p> 给一个字符串,和正整数 $ K $ ,求这个字符串中出现次数至少为 $ K $ 的串的最大长度。</p></li><li><p>题解</p><ol><li>二分答案,然后将所有后缀在以 $ Rank $ 排序时的顺序进行分组,要求每一组的 $ LCP \leq mid$。最后看是否有一组的字符串个数大于等于 $ K $即可判断该案是否成立。</li></ol><ol><li>使用单调队列。维护一个递增的单调队列(因为要求最小值),并且当队头的位置和当前位置的差大于 $ K $ 时弹出队头。这样求可以快速求出任意一段长度为 $ K $ 的L后缀的 $ LCP $ 的最小值。</li></ol></li><li><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></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<=n;i++)</span><br><span class="line">{</span><br><span class="line"> <span class="keyword">while</span>(q.size()&&height[q.back()]>=height[i]) q.pop_back();</span><br><span class="line"> q.push_back(i);</span><br><span class="line"> <span class="keyword">while</span>(q.size()&&i-q.front()+<span class="number">1</span>>k<span class="number">-1</span>) q.pop_front();</span><br><span class="line"> ans=max(ans,height[q.front()]);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol><h2 id="重复旋律二"><a href="#重复旋律二" class="headerlink" title="重复旋律二"></a>重复旋律二</h2><ol><li><p>链接</p><p> <a href="http://hihocoder.com/problemset/problem/1407" target="_blank" rel="noopener">后缀数组二·重复旋律2</a></p></li><li><p>题意</p><p> 给定一个串,求<strong>不重叠的</strong>出现次数至少为 $ 2 $ 的最长子串。</p></li><li><p>题解</p><p> 二分答案,还是第一题那样分组,然后看看每一组中最大的 $ sa $ 和最小的 $ sa $ 之差是否大于等于mid。</p></li><li><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><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">check</span><span class="params">(<span class="keyword">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> minsa=<span class="number">0</span>,maxsa=<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">if</span>(height[i]<x)</span><br><span class="line"> {</span><br><span class="line"> minsa=sa[i];</span><br><span class="line"> maxsa=sa[i];</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> minsa=min(minsa,sa[i]);</span><br><span class="line"> maxsa=max(maxsa,sa[i]);</span><br><span class="line"> <span class="keyword">if</span>(maxsa-minsa>=x) <span class="keyword">return</span> <span class="literal">true</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="literal">false</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol><h2 id="重复旋律三"><a href="#重复旋律三" class="headerlink" title="重复旋律三"></a>重复旋律三</h2><ol><li><p>链接</p><p> <a href="http://hihocoder.com/problemset/problem/1415" target="_blank" rel="noopener">后缀数组三·重复旋律3</a></p></li><li><p>题意</p><p> 求两个串的最长公共子串。</p></li><li><p>题解</p><p> 在一个串后加一个不存在的字符后将另一个串接上去,求后缀数组后直接按 $ Rank $ 顺序跑,看相邻两个是否在两个串中。如果是,用这两个串的 $ LCP $ 更新答案。</p></li><li><p>核心代码</p></li></ol><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">2</span>;i<=n;i++)</span><br><span class="line"> <span class="keyword">if</span>(((<span class="number">1</span><=sa[i]&&sa[i]<=len1)!=(<span class="number">1</span><=sa[i<span class="number">-1</span>]&&sa[i<span class="number">-1</span>]<=len1))&&i!=len1+<span class="number">1</span>&&i<span class="number">-1</span>!=len1+<span class="number">1</span>)</span><br><span class="line"> ans=max(ans,height[i]);</span><br></pre></td></tr></table></figure><h2 id="重复旋律四"><a href="#重复旋律四" class="headerlink" title="重复旋律四"></a>重复旋律四</h2><ol><li><p>链接</p><p> <a href="http://hihocoder.com/problemset/problem/1419" target="_blank" rel="noopener">后缀数组四·重复旋律4</a></p></li><li><p>题意</p><p> 给定一个串,求这个串的一个子串,使得这个子串是由数个相同的小子串构成的,且使重复次数最多。</p></li><li><p>题解</p><p> 枚举小子串的长度 $ len $ ,然后将原串每隔 $ len $ 个点设一个特殊点。然后枚举每个特殊点,求出它与下一个特殊点的 $ LCP $ 。这两个特殊点的答案就是 $ \left \lfloor \frac{LCP}{len}+1 \right \rfloor $ 。然后考虑如果左端点不是在特殊点上的情况。我们将枚举的这个特殊点设为 $ p $ ,则我们只要看 $ p+l-LCP(p,p+l)\%len $ 这个点是否能使答案增加即可。</p><p> 由调和级数可知,总复杂度 $ O(nlogn) $ 。</p></li><li><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><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span>(<span class="keyword">int</span> len=<span class="number">1</span>;len<=n;len++)</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+len<=n;i+=len)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> R=query(i,i+len);</span><br><span class="line"> ans=max(ans,R/len+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">if</span>(i>=len-R%len)</span><br><span class="line"> ans=max(ans,query(i-len+R%len,i+R%len)/len+<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 后缀数组 </tag>
</tags>
</entry>
<entry>
<title>后缀数组模板</title>
<link href="/2018/01/22/%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84%E6%A8%A1%E6%9D%BF/"/>
<url>/2018/01/22/%E5%90%8E%E7%BC%80%E6%95%B0%E7%BB%84%E6%A8%A1%E6%9D%BF/</url>
<content type="html"><![CDATA[<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="function"><span class="keyword">void</span> <span class="title">get_sa</span><span class="params">(<span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> m=<span class="number">127</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++) Rank[i]=str[i],tp[i]=i;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<=m;i++) sum[i]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) sum[Rank[tp[i]]]++;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]+=sum[i<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--) sa[sum[Rank[tp[i]]]--]=tp[i];</span><br><span class="line"> <span class="keyword">int</span> p=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> len=<span class="number">1</span>;p<n;m=p,len<<=<span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> p=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n-len+<span class="number">1</span>;i<=n;i++) tp[++p]=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 class="keyword">if</span>(sa[i]>len) tp[++p]=sa[i]-len;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<=m;i++) sum[i]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) sum[Rank[tp[i]]]++;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]+=sum[i<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--) sa[sum[Rank[tp[i]]]--]=tp[i];</span><br><span class="line"> swap(Rank,tp);</span><br><span class="line"> Rank[sa[<span class="number">1</span>]]=<span class="number">1</span>;</span><br><span class="line"> p=<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++)</span><br><span class="line"> Rank[sa[i]]=(tp[sa[i]]==tp[sa[i<span class="number">-1</span>]]&&tp[sa[i]+len]==tp[sa[i<span class="number">-1</span>]+len])?p:++p;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> _lst=<span class="number">0</span>,j;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;height[Rank[i++]]=_lst) <span class="comment">// i -> lpos</span></span><br><span class="line"> <span class="keyword">for</span>(_lst=_lst?_lst<span class="number">-1</span>:_lst,j=sa[Rank[i]<span class="number">-1</span>];str[j+_lst]==str[i+_lst];_lst++);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">get_st</span><span class="params">(<span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></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"> lg2[i]=lg2[i>><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><br><span class="line"> st[i][<span class="number">0</span>]=height[i];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> j=<span class="number">1</span>;j<=lg2[n];j++)</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">1</span><<(j<span class="number">-1</span>))<=n;i++)</span><br><span class="line"> st[i][j]=min(st[i][j<span class="number">-1</span>],st[i+(<span class="number">1</span><<(j<span class="number">-1</span>))][j<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">query</span><span class="params">(<span class="keyword">int</span> l,<span class="keyword">int</span> r)</span> <span class="comment">//l,r => Rank</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(l>r) swap(l,r);</span><br><span class="line"> ++l; <span class="comment">//notice</span></span><br><span class="line"> <span class="keyword">int</span> len=lg2[r-l+<span class="number">1</span>];</span><br><span class="line"> <span class="comment">//printf("%d %d %d %d %d\n",l,r,st[l][len],st[r-(1<<len)+1][len],len);</span></span><br><span class="line"> <span class="keyword">return</span> min(st[l][len],st[r-(<span class="number">1</span><<len)+<span class="number">1</span>][len]);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 模板 </category>
</categories>
<tags>
<tag> 后缀数组 </tag>
</tags>
</entry>
<entry>
<title>采集矿石题解</title>
<link href="/2018/01/16/%E9%87%87%E9%9B%86%E7%9F%BF%E7%9F%B3%E9%A2%98%E8%A7%A3/"/>
<url>/2018/01/16/%E9%87%87%E9%9B%86%E7%9F%BF%E7%9F%B3%E9%A2%98%E8%A7%A3/</url>
<content type="html"><![CDATA[<ol><li><p><strong>一句话题意:给定一个字符串和其每个位置相应的权值,求满足以下条件的子串个数:</strong></p><ol><li><p>子串所对应的权值和等于其在所有字串中的排名(从大到小)</p><p> (也就是第K大的子串权值和为K)</p></li><li><p>注意:相同的子串排名时算一个,但统计答案是分开算。</p></li></ol></li><li><p><strong>30pts做法</strong></p><p> <del>(暴力模拟)</del></p></li><li><p><strong>正解</strong></p><p> 首先看到是字符串的题,又没有匹配问题,那么肯定就和后缀有关了。<del>(因为我只会这么多)</del></p><p> 考虑后缀数组。</p><p> 我们考虑如何用后缀数组求一个串的本质不同的子串个数。</p><p> 一个串的本质不同的子串个数应为</p><p> $ \sum_{i=1}^{n} n-sa[i]-height[i]+1 $</p><p> 观察题目中的条件,可以发现若固定一个起始点,那么从它的开始的后缀的排名时单调下降的,而因为权值为非负的,所以子串的权值和是单调不降的,大概如下图所示。</p> <img src="/2018/01/16/采集矿石题解/1.png"><p> 接下来,我们就可以二分这个交点,如果有交点,那么 $ ans++ $ ,并记录当前方案,否则枚举下一个端点。</p><p> 并且如果按照Rank的顺序来枚举,可以发现一个后缀之前的子串个数是可以用前缀和进行优化的。</p><p> 经过 <del>严谨的</del> 推导,可以得出一个子串 $ (lpos,r) $ 的排名为 $ sum[n]-(sum[Rank[lpos]-1]+pos-lpos-height[Rank[lpos]]) $ 。</p><p> <strong>注意:这个式子仅适用于该子串不是与当前串的前一个排名的串的LCP的子串时成立。</strong></p><p> 即该式当且仅当 $ pos-lpos+1>height[Rank[lpos]] $ 时成立。</p><p> 接下来考虑如何处理 $ LCP $ 部分。</p><p> 第一个思路:</p><p> 开一个临时数组,记一下前面 $ LCP $ 部分的 $ Rank $ 然后在枚举时每次看一下当前临时数组的大小的 $ Height[i+1] $ 的大小,来判断是否需要更新临时数组。如果 $ size<height[i+1] $ 那么暴力更新临时数组,直至 $ size=height[i+1] $。</p><p> 可以发现,这种暴力处理的复杂度有可能被卡成 $ O(n^2) $。</p><p> <strong>这个思路的得分为76分</strong></p><p> 第二个思路:</p><p> 依照第一的思路,可以发现你要更新的这一段其实是一段连续下降的序列,且公差是 $ 1 $。</p><p> 可以使用线段树,该线段树支持区间赋值和区间加等差数列。</p><p> 也可以在线段树上维护这个位置所在 <strong>增加</strong> 的 $ LCP $ 的第一个位置,然后只在临时数组中记一下每次增加的第一位置的 $ Rank $ ,之后可以通过位置计算出当前位置的 $ Rank $ 。</p><p> 现在已经处理完了 $ LCP $ 部分的 $ Rank $ 了。我们发现,其实 $ LCP $ 部分的 $ Rank $ 也是单调下降的,这样我们可以在处理非 $ LCP $ 部分时一起二分。</p><p> 总复杂度 : $ O(nlogn) $</p><p> 至此,该问题已被完全解决。</p><p> STD:</p> <figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br></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"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="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"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><bitset></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><ctime></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> get_val(l,r) sumv[r]-sumv[l-1]</span></span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN=<span class="number">100010</span>;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">O</span>{</span></span><br><span class="line"> <span class="keyword">int</span> l,r;</span><br><span class="line"> <span class="keyword">bool</span> <span class="keyword">operator</span> < (O a)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">return</span> l<a.l;</span><br><span class="line"> }</span><br><span class="line">}ot[MAXN];</span><br><span class="line"><span class="keyword">int</span> t[MAXN<<<span class="number">2</span>];</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">pushup</span><span class="params">(<span class="keyword">int</span> x)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> t[x]=t[x<<<span class="number">1</span>]*(t[x<<<span class="number">1</span>]==t[x<<<span class="number">1</span>|<span class="number">1</span>]);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">pushdown</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(!t[x])</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> t[x<<<span class="number">1</span>]=t[x<<<span class="number">1</span>|<span class="number">1</span>]=t[x];</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">void</span> <span class="title">change</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> ql,<span class="keyword">int</span> qr,<span class="keyword">int</span> val)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(ql>r||qr<l)</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> <span class="keyword">if</span>(ql<=l&&r<=qr){</span><br><span class="line"> t[x]=val+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> pushdown(x,l,r);</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>(ql<=mid)</span><br><span class="line"> change(x<<<span class="number">1</span>,l,mid,ql,qr,val);</span><br><span class="line"> <span class="keyword">if</span>(qr>=mid+<span class="number">1</span>)</span><br><span class="line"> change(x<<<span class="number">1</span>|<span class="number">1</span>,mid+<span class="number">1</span>,r,ql,qr,val);</span><br><span class="line"> pushup(x);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="keyword">int</span> <span class="title">query</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> l,<span class="keyword">int</span> r,<span class="keyword">int</span> pos)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(t[x])</span><br><span class="line"> <span class="keyword">return</span> t[x]<span class="number">-1</span>;</span><br><span class="line"> pushdown(x,l,r);</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>(pos<=mid)</span><br><span class="line"> <span class="keyword">return</span> query(x<<<span class="number">1</span>,l,mid,pos);</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> <span class="keyword">return</span> query(x<<<span class="number">1</span>|<span class="number">1</span>,mid+<span class="number">1</span>,r,pos);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">char</span> str[MAXN];</span><br><span class="line">ll Rank[MAXN],sa[MAXN];</span><br><span class="line">ll sum[MAXN],tp[MAXN];</span><br><span class="line">ll height[MAXN],h[MAXN];</span><br><span class="line">ll val[MAXN],sumv[MAXN];</span><br><span class="line">ll tmprank[MAXN],tot;</span><br><span class="line"><span class="keyword">int</span> n;</span><br><span class="line">ll ans=<span class="number">0</span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">get_sa</span><span class="params">(<span class="keyword">int</span> n)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> m=<span class="number">127</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++) Rank[i]=str[i],tp[i]=i;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<=m;i++) sum[i]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) sum[Rank[tp[i]]]++;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]+=sum[i<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--) sa[sum[Rank[tp[i]]]--]=tp[i];</span><br><span class="line"> <span class="keyword">int</span> p=<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> len=<span class="number">1</span>;p<n;len<<=<span class="number">1</span>,m=p)</span><br><span class="line"> {</span><br><span class="line"> p=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n-len+<span class="number">1</span>;i<=n;i++) tp[++p]=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 class="keyword">if</span>(sa[i]>len) tp[++p]=sa[i]-len;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">0</span>;i<=m;i++) sum[i]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) sum[Rank[tp[i]]]++;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]+=sum[i<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--) sa[sum[Rank[tp[i]]]--]=tp[i];</span><br><span class="line"> swap(Rank,tp);Rank[sa[<span class="number">1</span>]]=<span class="number">1</span>;p=<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++)</span><br><span class="line"> Rank[sa[i]]=(tp[sa[i]]==tp[sa[i<span class="number">-1</span>]]&&tp[sa[i]+len]==tp[sa[i<span class="number">-1</span>]+len])?p:++p;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> lst=<span class="number">0</span>,j;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;h[i]=lst,height[Rank[i++]]=lst)</span><br><span class="line"> <span class="keyword">for</span>(lst=lst?lst<span class="number">-1</span>:lst,j=sa[Rank[i]<span class="number">-1</span>];str[j+lst]==str[i+lst];++lst);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">get_rank</span><span class="params">(<span class="keyword">int</span> lpos,<span class="keyword">int</span> pos)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(pos-lpos+<span class="number">1</span>>height[Rank[lpos]]) <span class="keyword">return</span> sum[n]-(sum[Rank[lpos]<span class="number">-1</span>]+pos-lpos-height[Rank[lpos]]);</span><br><span class="line"> <span class="keyword">else</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> pre=query(<span class="number">1</span>,<span class="number">1</span>,n,pos-lpos+<span class="number">1</span>);</span><br><span class="line"> <span class="keyword">return</span> tmprank[pre]+pre-(pos-lpos+<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"><span class="keyword">int</span> tttt;</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="function"></span>{</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%s"</span>,str+<span class="number">1</span>);</span><br><span class="line"> n=<span class="built_in">strlen</span>(str+<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="built_in">scanf</span>(<span class="string">"%lld"</span>,&val[i]),sumv[i]=sumv[i<span class="number">-1</span>]+val[i];</span><br><span class="line"> get_sa(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"> sum[i]=n-sa[i]-height[i]+<span class="number">1</span>+sum[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<=n;i++) <span class="comment">//枚举Rank</span></span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">int</span> L=sa[i],R=n,lpos=sa[i];</span><br><span class="line"> <span class="keyword">while</span>(L<R)</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>(get_val(lpos,mid)<get_rank(lpos,mid))</span><br><span class="line"> L=mid+<span class="number">1</span>;</span><br><span class="line"> <span class="keyword">else</span> R=mid;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>(get_val(lpos,L)==get_rank(lpos,L))</span><br><span class="line"> ot[++ans]={lpos,L};</span><br><span class="line"> <span class="keyword">if</span>(i!=n&&height[i]<height[i+<span class="number">1</span>])</span><br><span class="line"> tmprank[height[i]+<span class="number">1</span>]=get_rank(sa[i],sa[i]+height[i]),</span><br><span class="line"> change(<span class="number">1</span>,<span class="number">1</span>,n,height[i]+<span class="number">1</span>,height[i+<span class="number">1</span>],height[i]+<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> sort(ot+<span class="number">1</span>,ot+<span class="number">1</span>+ans);</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">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=ans;i++)</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%d %d\n"</span>,ot[i].l,ot[i].r);</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ol>]]></content>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 后缀数组 </tag>
</tags>
</entry>
<entry>
<title>字符串注意事项</title>
<link href="/2018/01/15/%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/"/>
<url>/2018/01/15/%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9/</url>
<content type="html"><![CDATA[<h2 id="后缀数组"><a href="#后缀数组" class="headerlink" title="后缀数组"></a>后缀数组</h2><ol><li>求 $ Suffix[i]~Suffix[j] $ 的LCP: $ min\l{Height[k]\r} (Rank[i]\le k \le j-1) $</li></ol>]]></content>
<categories>
<category> 注意&总结 </category>
</categories>
<tags>
<tag> 后缀数组 </tag>
</tags>
</entry>
<entry>
<title>BZOJ4199&&洛谷2178 [NOI2015]品酒大会</title>
<link href="/2018/01/13/BZOJ4199&&%E6%B4%9B%E8%B0%B72178%20%5BNOI2015%5D%E5%93%81%E9%85%92%E5%A4%A7%E4%BC%9A/"/>
<url>/2018/01/13/BZOJ4199&&%E6%B4%9B%E8%B0%B72178%20%5BNOI2015%5D%E5%93%81%E9%85%92%E5%A4%A7%E4%BC%9A/</url>
<content type="html"><![CDATA[<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">一道后缀数组题</span><br><span class="line"></span><br><span class="line">先求出height,然后从大到小枚举每个height。</span><br><span class="line"></span><br><span class="line">然后对于每个height值,两端的集合中任意一对后缀都是这个height。</span><br><span class="line"></span><br><span class="line">我们统计答案之后合并两端的集合,用并查集维护即可。</span><br><span class="line"></span><br><span class="line">因为我们是从大到小枚举的Height,所以</span><br></pre></td></tr></table></figure><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><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</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"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cmath></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><algorithm></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><cstring></span></span></span><br><span class="line"><span class="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"><map></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><set></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><queue></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stack></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><bitset></span></span></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="built_in">std</span>;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">long</span> <span class="keyword">long</span> ll;</span><br><span class="line"><span class="keyword">typedef</span> <span class="keyword">unsigned</span> <span class="keyword">long</span> <span class="keyword">long</span> ull;</span><br><span class="line"><span class="keyword">const</span> <span class="keyword">int</span> MAXN=<span class="number">300010</span>;</span><br><span class="line"><span class="keyword">const</span> ll INF=(<span class="number">1l</span>l<<<span class="number">62</span>);</span><br><span class="line"><span class="keyword">char</span> str[MAXN];</span><br><span class="line"><span class="keyword">int</span> sa[MAXN],Rank[MAXN],tp[MAXN],height[MAXN],sum[MAXN];</span><br><span class="line"><span class="keyword">int</span> fa[MAXN],siz[MAXN],maxv[MAXN],minv[MAXN];</span><br><span class="line"><span class="keyword">int</span> n,val[MAXN];</span><br><span class="line">ll ans2[MAXN],ans1[MAXN];</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">get_sa</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> m=<span class="number">127</span>;</span><br><span class="line"> <span class="keyword">int</span> p=<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++) tp[i]=i,Rank[i]=str[i];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) sum[Rank[tp[i]]]++;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]+=sum[i<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--) sa[sum[Rank[tp[i]]]--]=tp[i];</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> len=<span class="number">1</span>;p<n;m=p,len<<=<span class="number">1</span>)</span><br><span class="line"> {</span><br><span class="line"> p=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n-len+<span class="number">1</span>;i<=n;i++) tp[++p]=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 class="keyword">if</span>(sa[i]>len) tp[++p]=sa[i]-len;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++) sum[Rank[tp[i]]]++;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=m;i++) sum[i]+=sum[i<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--) sa[sum[Rank[tp[i]]]--]=tp[i];</span><br><span class="line"> swap(Rank,tp);</span><br><span class="line"> Rank[sa[<span class="number">1</span>]]=<span class="number">1</span>;p=<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++)</span><br><span class="line"> Rank[sa[i]]=(tp[sa[i<span class="number">-1</span>]]==tp[sa[i]]&&tp[sa[i<span class="number">-1</span>]+len]==tp[sa[i]+len])?p:++p;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> lst=<span class="number">0</span>,j;</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;height[Rank[i++]]=lst)</span><br><span class="line"> <span class="keyword">for</span>(lst=lst?lst<span class="number">-1</span>:lst,j=sa[Rank[i]<span class="number">-1</span>];str[j+lst]==str[i+lst];++lst);</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="function"></span>{</span><br><span class="line"> <span class="keyword">return</span> x==fa[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">merge</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="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(siz[x]<siz[y]) swap(x,y); <span class="comment">// y->x</span></span><br><span class="line"> maxv[x]=max(maxv[x],maxv[y]);</span><br><span class="line"> minv[x]=min(minv[x],minv[y]);</span><br><span class="line"> siz[x]+=siz[y];</span><br><span class="line"> fa[y]=x;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">bool</span> <span class="title">cmp</span><span class="params">(<span class="keyword">int</span> x,<span class="keyword">int</span> y)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span>(height[x]!=height[y])</span><br><span class="line"> <span class="keyword">return</span> height[x]>height[y];</span><br><span class="line"> <span class="keyword">return</span> x<y;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></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="built_in">scanf</span>(<span class="string">"%s"</span>,str+<span class="number">1</span>);</span><br><span class="line"> get_sa();</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=<span class="number">1</span>;i<=n;i++)</span><br><span class="line"> <span class="built_in">scanf</span>(<span class="string">"%d"</span>,&val[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++) siz[i]=<span class="number">1</span>,fa[i]=i,maxv[i]=minv[i]=val[sa[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++) tp[i]=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">0</span>;i<n;i++) ans2[i]=-INF;</span><br><span class="line"> sort(tp+<span class="number">1</span>,tp+n,cmp);</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><br><span class="line"> <span class="keyword">int</span> x=find(tp[i]),y=find(tp[i]<span class="number">-1</span>);</span><br><span class="line"> ans1[height[tp[i]]]+=<span class="number">1l</span>l*siz[x]*siz[y];</span><br><span class="line"> ans2[height[tp[i]]]=max(ans2[height[tp[i]]],<span class="number">1l</span>l*maxv[x]*maxv[y]);</span><br><span class="line"> ans2[height[tp[i]]]=max(ans2[height[tp[i]]],<span class="number">1l</span>l*maxv[x]*minv[y]);</span><br><span class="line"> ans2[height[tp[i]]]=max(ans2[height[tp[i]]],<span class="number">1l</span>l*minv[x]*maxv[y]);</span><br><span class="line"> ans2[height[tp[i]]]=max(ans2[height[tp[i]]],<span class="number">1l</span>l*minv[x]*minv[y]);</span><br><span class="line"> merge(x,y);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">for</span>(<span class="keyword">int</span> i=n<span class="number">-2</span>;i>=<span class="number">0</span>;i--)</span><br><span class="line"> ans1[i]+=ans1[i+<span class="number">1</span>],</span><br><span class="line"> ans2[i]=max(ans2[i],ans2[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">0</span>;i<=n<span class="number">-1</span>;i++)</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"%lld %lld\n"</span>,ans1[i],ans2[i]==-INF?<span class="number">0</span>:ans2[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>
<categories>
<category> 题解 </category>
</categories>
<tags>
<tag> 后缀数组 </tag>
</tags>
</entry>
<entry>
<title>重要反演推论</title>
<link href="/2018/01/13/%E9%87%8D%E8%A6%81%E5%8F%8D%E6%BC%94%E6%8E%A8%E8%AE%BA/"/>
<url>/2018/01/13/%E9%87%8D%E8%A6%81%E5%8F%8D%E6%BC%94%E6%8E%A8%E8%AE%BA/</url>
<content type="html"><![CDATA[<p>$ \varphi \times 1=id $</p><p>$ μ \times id=\varphi $</p><p>$ μ \times 1=\varepsilon $</p><p>$ \varepsilon \times1 =1 $</p><p>$ \sum _{i=1}^{n}\sum_{d|i}{d\cdot\varphi(d)}=\sum _ {i=1}^{n}\sum _{d|i}(\frac{i}{d})\cdot \varphi(\frac{i}{d})=\sum_{i=1}^{n}\sum_{\frac{i}{d}=1} ^{\lfloor\frac{n}{i}\rfloor} (\frac{i}{d})\cdot \varphi(\frac{i}{d}) =\sum_{i=1}^{n}\sum_{d=1}^{\lfloor\frac{n}{i}\rfloor}{d\cdot\varphi(d)} $</p>]]></content>
<categories>
<category> 注意&总结 </category>
</categories>
<tags>
<tag> 莫比乌斯反演 </tag>
</tags>
</entry>
<entry>
<title>北京游记Day5</title>
<link href="/2018/01/13/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day5/"/>
<url>/2018/01/13/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day5/</url>
<content type="html"><![CDATA[<h1 id="一-最小树形图"><a href="#一-最小树形图" class="headerlink" title="一.最小树形图"></a>一.最小树形图</h1><h2 id="1-基础"><a href="#1-基础" class="headerlink" title="1. 基础"></a>1. 基础</h2><ol><li><p>定义</p><p> 最小树形图,就是给有向带权图中指定一个特殊的点 $ root $ ,求一棵以 $ root $ 为根的有向生成树T,并且T中所有边的总权值最小。</p></li></ol><h2 id="2-朱刘算法"><a href="#2-朱刘算法" class="headerlink" title="2. 朱刘算法"></a>2. 朱刘算法</h2><ol><li><p>复杂度 $ O(VE) $</p></li><li><p>算法流程</p><ol><li><p>对固定根 $ root $ 进行一遍 $ DFS $ 判断是否存在最⼩小树形图。</p></li><li><p>为除了了 $ root $ 之外的每个顶点选定一条最小的入边(用 $ pre[u] $ 记录顶点 $ u $ 最小入边的起点)。</p></li><li><p>判断2中构造的⼊入边集合是否存在有向环,如果不不存在,那么这个集合就是该图的最<br>⼩小树形图。</p></li><li><p>如果3中判断出现有向环,则消环缩点。设 $ (u,v,w) $ 表示从 $ u $ 到 $ v $ 的权为 $ w $的边。</p><p>假设3中判断出的有向环缩为新顶点 $ new $ ,若 $ u $ 位于环上,并设环中指向 $ u $ 的边权是 $ ω[u] $ 。</p><p>那么对于每条从u出发的边 $ (u,v,w) $ ,在新图中连接 $ (new,v,w) $ ,对于每条进⼊入u的边 $ (in,u,w) $ ,在新图中建⽴立边 $ (in,new,w-ω[u]) $ 。</p><p>新图⾥里里最⼩小树形图的权加上旧图中被收缩的环的权和,就是原图中最⼩小树形图的权值。重复2,3,4。</p></li><li><p>中判断⽆无有向环,返回权值。</p></li></ol></li></ol><h2 id="3-平面图"><a href="#3-平面图" class="headerlink" title="3. 平面图"></a>3. 平面图</h2><h1 id="二-字符串"><a href="#二-字符串" class="headerlink" title="二.字符串"></a>二.字符串</h1><h2 id="1-AC自动机"><a href="#1-AC自动机" class="headerlink" title="1. AC自动机"></a>1. AC自动机</h2><h2 id="2-后缀自动机"><a href="#2-后缀自动机" class="headerlink" title="2. 后缀自动机"></a>2. 后缀自动机</h2><ol><li><p>自动机:</p><ol><li><p>构成:</p><ol><li><p>$ alpha $ : 字符集</p></li><li><p>$ state $ : 状态集合</p></li><li><p>$ init $: 初始状态</p></li><li><p>$ end $ : 结束状态集合</p></li><li><p>$ trans $ : 状态转移函数</p></li><li><p>$ trans $ 函数</p></li></ol><p>$ trans(s,ch) $ 表示当前状态是 $ S $ ,读入字符 $ ch $ 后的状态</p><p>$ trans(s,str) $ 表示当前状态是$ S $ ,读入字符串 $ str $ 后的状态</p><ol><li>杂项</li></ol><p>自动机A能识别的字符串就是所有使得 $ trans(init,x)∈end $ 的字符串x即为 $ Reg(A) $</p><p>从状态S开始可被识别的字符串集合记为 $ Reg(S) $</p></li></ol></li><li><p>后缀自动机</p><ol><li><p>定义</p><p> 给定字符串 $ S $</p><p> $ S $的后缀自动机(SAM)是能够识别所有 $ S $ 的所有后缀的自动机</p><p> 即 $ SAM(x)=True $ ,当且仅当 $ x $ 是 $ S $ 的后缀</p></li><li><p>最简单的实现</p><p> 后缀树:将所有后缀插入trie中</p><p> $ O(n^2) $</p><p> <del>太菜了</del></p></li><li><p>最简状态后缀自动机</p><ol><li><p>大小是线性的</p></li><li><p>假如我们得到了最简状态后缀自动机SAM</p><p>$ ST(str)=trans(init,str) $</p><p>令母串为S,他的后缀的集合为 $ Suf $ ,他的连续子串的集合为 $ Fac $</p><p>从位置 $ a $ 开始的后缀为 $ Suffix(a) $</p><p>$ S[l,r) $ 表示S中 $ [l,r) $ 区间构成的子串</p><p>下标从 $ 0 $ 开始</p><p>对于字符串 $ x $ ,若 $ x $ 不属于 $ Fac $ ,那么 $ ST(x)=null $</p><p>对于字符串 $ x $ ,若 $ x $ 属于 $ Fac $ ,那么 $ ST(x)!=null $</p></li></ol></li></ol></li></ol>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> 最小树形图 </tag>
<tag> 后缀自动机 </tag>
</tags>
</entry>
<entry>
<title>北京游记Day4</title>
<link href="/2018/01/13/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day4/"/>
<url>/2018/01/13/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day4/</url>
<content type="html"><![CDATA[<h1 id="树分治"><a href="#树分治" class="headerlink" title="树分治"></a>树分治</h1><h2 id="1-分治"><a href="#1-分治" class="headerlink" title="1.分治"></a>1.分治</h2><ol><li><p>分治要求</p><ol><li><p>问题缩小到一定规模是就可以容易的解决</p></li><li><p>该问题可以分解为若干个规模较小的相同问题,即用最优子结构的性质</p></li><li><p>利用该问题分解出的子问题的解可以合并为该问题的解</p></li><li><p>该问题所分解的各个子问题是相互独立的,不包含公共子问题</p></li></ol></li></ol><h2 id="2-树"><a href="#2-树" class="headerlink" title="2. 树"></a>2. 树</h2><ol><li><p>树的定义</p><p> 没有环的连通图</p></li><li><p>性质</p><ol><li><p>去掉树的一条边后所得的图不连通</p></li><li><p>在树中添加一条边后所得的图一定存在环</p></li><li><p>每一对顶点U V间有且仅有一条路径</p></li></ol></li></ol><h2 id="3-点分治"><a href="#3-点分治" class="headerlink" title="3. 点分治"></a>3. 点分治</h2><ol><li><p>基本方法</p><p> 首先选取一个点将无根树转为有根树,在递归处理每一颗以根节点的儿子为根的子树</p></li><li><p>例题</p><ol><li><p><a href="http://poj.org/problem?id=1741" target="_blank" rel="noopener">POJ1741</a></p><p> 求树上距离小于等于K的点对有多少 (N<=10000)</p><pre><code> 点分治+DP</code></pre></li><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=2599" target="_blank" rel="noopener">BZOJ2599</a></p></li></ol></li></ol><h2 id="4-边分治"><a href="#4-边分治" class="headerlink" title="4. 边分治"></a>4. 边分治</h2><ol><li><p>基本方法</p><p> <del>自己YY</del></p></li><li><p>例题</p><ol><li><a href="http://www.spoj.com/problems/QTREE4" target="_blank" rel="noopener">QTREE4</a><br>或<a href="http://www.lydsy.com/JudgeOnline/problem.php?id=1095" target="_blank" rel="noopener">BZOJ1095</a>(题意相同)</li></ol></li></ol><h2 id="5-基于链的分治-树链剖分"><a href="#5-基于链的分治-树链剖分" class="headerlink" title="5. 基于链的分治(树链剖分)"></a>5. 基于链的分治(树链剖分)</h2><ol><li>题目:[Query On a Tree]</li></ol><h3 id="略"><a href="#略" class="headerlink" title="略"></a>略</h3><ol><li><p>Astar2008 黑白树</p></li><li><p><a href="http://www.spoj.com/problems/QTREE4" target="_blank" rel="noopener">QTREE4</a></p></li></ol><h2 id="6-基于询问的分治-CDQ分治"><a href="#6-基于询问的分治-CDQ分治" class="headerlink" title="6. 基于询问的分治 (CDQ分治)"></a>6. 基于询问的分治 <del>(CDQ分治)</del></h2><ol><li><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=2001" target="_blank" rel="noopener">BZOJ2001</a></li></ol><h2 id="7-模拟退火"><a href="#7-模拟退火" class="headerlink" title="7. 模拟退火"></a>7. 模拟退火</h2>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> 点分治 </tag>
<tag> 边分治 </tag>
<tag> 树链剖分 </tag>
</tags>
</entry>
<entry>
<title>北京游记Day3</title>
<link href="/2018/01/13/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day3/"/>
<url>/2018/01/13/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day3/</url>
<content type="html"><![CDATA[<h1 id="数论"><a href="#数论" class="headerlink" title="数论"></a>数论</h1><h2 id="1-模方程"><a href="#1-模方程" class="headerlink" title="1. 模方程"></a>1. 模方程</h2><ol><li><p>线性同余方程</p></li><li><p>线性同余方程组</p></li><li><p>主要内容</p><ol><li>考虑形如 $ a^b\equiv c \mod m $ 的方程</li></ol></li></ol><p>下文模方程均为 $ f(x)\equiv 0 \mod m $</p><ol><li><p>非线性同余方程</p><ol><li>因式分解</li></ol></li><li><p>离散对数问题</p><ol><li><p>考虑 $ f(x)=a^x+c $ ,则问题演变为离散对数问题</p></li><li><p>求解方法</p><ol><li><p>m为质数</p></li><li><p>a和m互质</p></li><li><p>一般情况</p></li></ol></li></ol></li></ol><h2 id="2-原根"><a href="#2-原根" class="headerlink" title="2. 原根"></a>2. 原根</h2><ol><li><p>定义</p><p> 考察方程 $ a \cdot x ≡1(mod m) $,若 $ gcd(a,m)=1 $ ,则方程一定有解 $ x=\varphi(m) $</p><p> 我们定义在上述情况下,方程最小的解为 $ x=δ m (a) $ ,</p><p> 则显然有 $ δ m (a)≤φ(m) $ ,若a满足条件 $ δ m (a)=φ(m) $ ,我们就称a是模m的原根</p></li><li><p>群论</p><ol><li><p>定义</p><p> G={S,⊕}</p></li><li><p>性质</p><ol><li><p>封闭性</p></li><li><p>$ a⊕(b⊕c)=(a⊕b)⊕c $</p></li><li><p>存在单位元</p></li><li><p>存在逆元</p></li></ol></li></ol></li><li><p>原根的应用</p><ol><li>模数为指数的高次剩余问题 $ x^a\equiv b \mod p $</li></ol></li></ol><h2 id="3-积性函数"><a href="#3-积性函数" class="headerlink" title="3. 积性函数"></a>3. 积性函数</h2><ol><li><p>Dirichlet特征</p><ol><li><p>有周期</p></li><li><p>完全积性</p></li><li><p>$ f(1)=1 $</p></li></ol></li><li><p>积性函数与完全积性函数</p></li><li><p>常用积性函数</p><ol><li><p>欧拉函数($\varphi$):$ \varphi(n) $ 表示1~n中与n互质的数的个数</p></li><li><p>莫比乌斯函数($\mu$):$ \mu(1)=1 $ ,若 $ n(n>1) $ 含有多重质因数,则 $ μ(n)=0 $ ,否则 $ μ(n)=(-1)^r $ ,$r$表示$n$的质因数个数(与容斥比较像)</p></li><li><p>除数函数($ σ $):一类函数,每个非负整数x都对应一个除数函数$σ x $,$σ x (n)$表示n的因数的x次方之和</p></li></ol></li><li><p>欧拉筛筛欧拉函数</p></li><li><p>欧拉函数的推论</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">当n>1时,1~n中与n互质的数的和为n*φ(n)/2</span><br></pre></td></tr></table></figure></li><li><p>欧拉定理</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">若n,a∈N满足gcd(n,a)=1,则a^φ(n) ≡1(mod n)</span><br></pre></td></tr></table></figure></li><li><p>扩展欧拉定理</p> <figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">设a,b,n∈N,若:</span><br><span class="line">• gcd(n,a)=1,则a^b ≡a^b mod φ(n) (mod n)</span><br><span class="line">• gcd(n,a)≠1,b≤φ(n),则用快速幂计算</span><br><span class="line">• gcd(n,a)≠1,b>φ(n),则a^b ≡a^(b mod φ(n))+φ(n) (mod n)</span><br></pre></td></tr></table></figure></li><li><p>莫比乌斯函数的积性函数</p></li><li><p>其他积性函数</p><figure class="highlight plain"><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">• 常函数(1):∀n∈N,1(n)=1</span><br><span class="line">• 单位函数(id):∀n∈N,id(n)=n</span><br><span class="line">• 幂函数(id k ):∀n∈N,id k (n)=n k</span><br><span class="line">• 狄利克雷卷积单位函数(ε):ε(1)=1,∀n>1,ε(n)=0</span><br><span class="line">• 元函数(e):这是一个由命题映射到N的特殊函数,</span><br><span class="line"> e[P]=1当且仅当P为真,否则e[P]=0</span><br><span class="line">• 倒数函数(f):∀n∈N,f(n)=1/n</span><br><span class="line">• 值得一提的是,这些函数都是完全积性函数</span><br></pre></td></tr></table></figure></li><li><p>保留 狄利克雷</p></li><li><p>两个重要推论</p><ol><li><p>$ \mu \times 1=\varepsilon $</p></li><li><p>$ \varphi \times 1=id $</p></li></ol></li><li><p>莫比乌斯反演定理</p><p>$ f×1=g↔μ×g=f $</p></li><li><p>四个卷积结论:</p><ol><li><p>$ \varphi \times 1=id $</p></li><li><p>$ μ \times id=\varphi $</p></li><li><p>$ μ \times 1=\varepsilon $</p></li><li><p>$ \varepsilon \times1 =1 $</p></li></ol></li></ol>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> 莫比乌斯反演 </tag>
<tag> 模方程 </tag>
<tag> 离散对数 </tag>
<tag> 原根 </tag>
<tag> 积性函数 </tag>
</tags>
</entry>
<entry>
<title>北京笔记Day2</title>
<link href="/2018/01/12/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day2/"/>
<url>/2018/01/12/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day2/</url>
<content type="html"><![CDATA[<h1 id="数学-科普"><a href="#数学-科普" class="headerlink" title="数学 (科普)"></a>数学 <del>(科普)</del></h1><h2 id="1-求导"><a href="#1-求导" class="headerlink" title="1. 求导"></a>1. 求导</h2><ol><li><p>定义</p><p>$ f{}’(x)=\lim_{\Delta x\rightarrow 0}\frac{f(x+ \Delta x)-f(x)}{\Delta x} $</p></li><li><p>公式</p><ol><li><p>$ (x^{\alpha})’=\alpha x^{\alpha-1} $</p></li><li><p>$ (e^x)’=e^x $</p></li><li><p>$ (\ln x)’ = \frac{1}{x} $</p></li><li><p>$ (sin(x))’=cos(x) $</p></li><li><p>$ (a^x)’=a^x \ln a $</p></li><li><p>$ (f(x)+g(x))’=f’(x)+g’(x) $</p></li><li><p>$ (f(x)-g(x))’=f’(x)-g’(x) $</p></li><li><p>$ (f(x)g(x))’=f’(x)g(x)-g’(x)f(x) $</p></li><li><p>$ (f(x)/g(x))’=\frac{f’(x)g(x)-g’(x)f(x)}{g^2(x)} $</p></li></ol></li><li><p>链式法则</p></li><li><p>导数求最值</p></li><li><p>多元函数求偏导</p></li><li><p>例题</p><ol><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=3528" target="_blank" rel="noopener">BZOJ 3528</a></p></li><li><p>最小二乘法 <del>(没听懂)</del></p></li></ol></li></ol><h2 id="2-积分"><a href="#2-积分" class="headerlink" title="2. 积分"></a>2. 积分</h2><ol><li><p>定义</p><p> 若有 $F’(x)=f(x) $</p><p> 则有 $ \int_{l}^{r}f(x)dx=F(b)-F(a) $</p></li><li><p>使用</p><ol><li><p>杜教筛复杂度证明</p></li><li><p>调和级数</p><p>$ \sum_{i=1}^{n} O(\frac{1}{n}) = ? $</p><p>$ \sum_{n=1}^k \, \frac{1}{n} \;>\; \int_1^{k+1} \frac{1}{x}\,dx \;=\; \ln(k+1). $</p></li></ol></li></ol><h2 id="3-概率与期望"><a href="#3-概率与期望" class="headerlink" title="3. 概率与期望"></a>3. 概率与期望</h2><p><del>见PDF</del></p><h1 id="数据结构"><a href="#数据结构" class="headerlink" title="数据结构"></a>数据结构</h1><h2 id="1-莫队"><a href="#1-莫队" class="headerlink" title="1. 莫队"></a>1. 莫队</h2><p><del>PS:(我也不知道为啥这个算数据结构)</del></p><ol><li><p>要求</p><ol><li><p>若已知 $ [L,R] $ 的信息,可快速求出 $ [L+-1,R] $ 和 $ [L,R+-1] $ 的信息</p></li><li><p>离线</p></li><li><p>只有询问</p></li><li><p>时间复杂度 $ O(n\sqrt n) $</p></li></ol></li><li><p>例题</p><ol><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=2038" target="_blank" rel="noopener">小Z的袜子</a></p></li><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=2821" target="_blank" rel="noopener">作诗<del>(分块)</del></a></p></li></ol></li><li><p>在线 <del>(即为分块。。)</del></p></li></ol><h2 id="2-莫队扩展"><a href="#2-莫队扩展" class="headerlink" title="2. 莫队扩展"></a>2. 莫队扩展</h2><ol><li><p>带修莫队</p><ol><li><p>做法</p><ol><li><p>设 $ siz=n^{\frac{2}{3}} $ 或 $ siz=n^{\frac{1}{3}} $</p></li><li><p>对询问按 $ (l/s,r/s,t) $ 排序</p></li><li><p><del>乱搞</del></p></li></ol></li><li><p>复杂度 $ O(n^{\frac{5}{3}}) $</p></li><li><p>在线 <del>(即为分块。。)</del></p></li></ol></li><li><p><del>(莫队上树)</del> 树上莫队</p><ol><li><p>转为DFS序后在DFS序上莫队</p></li><li><p><code>in(a)</code> 表示点<code>a</code>在进入DFS序的第一个位置</p></li><li><p>以 $ (in(a)/s,in(b)) $ 排序</p></li></ol></li></ol><h2 id="3-动态树-LCT"><a href="#3-动态树-LCT" class="headerlink" title="3. 动态树 (LCT)"></a>3. 动态树 <del>(LCT)</del></h2>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> 数学 </tag>
<tag> 莫队 </tag>
<tag> LCT </tag>
</tags>
</entry>
<entry>
<title>北京笔记Day1</title>
<link href="/2018/01/12/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day1/"/>
<url>/2018/01/12/%E5%8C%97%E4%BA%AC%E6%B8%B8%E8%AE%B0Day1/</url>
<content type="html"><![CDATA[<h2 id="分治"><a href="#分治" class="headerlink" title="分治"></a>分治</h2><p><del>(略)</del></p><h2 id="复杂度分析"><a href="#复杂度分析" class="headerlink" title="复杂度分析"></a>复杂度分析</h2><p>$ T(n)=2 * T(n/2)+O(kn) \Rightarrow O(kn*logn) $</p><h2 id="CDQ分治"><a href="#CDQ分治" class="headerlink" title="CDQ分治"></a>CDQ分治</h2><ol><li><p>适用条件:</p><ol><li><p>离线算法</p></li><li><p>每次修改操作对答案贡献独立,操作互不干扰</p></li></ol></li><li><p>简易模型</p><p> 计算 $ [mid+1,r] $</p><p> 计算 $ [mid+1,r] $</p></li><li><p>三维偏序 $ (a,b,c) $</p><ol><li><p>按 $ a $ 属性排序</p></li><li><p>用两个指针扫 $ b_{i}\leq b_{j} $</p></li><li><p>用树状数组维护 $ c $ 属性</p></li></ol></li><li><p>例题 <del>(玄学时间)</del></p><ol><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=1176" target="_blank" rel="noopener">BZOJ 1176</a></p><p> …</p></li><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=2716" target="_blank" rel="noopener">BZOJ 2716</a></p><p> …</p></li><li><p><a href="http://acm.hdu.edu.cn/showproblem.php?pid=5127" target="_blank" rel="noopener">HDU 5127</a></p><p> …</p></li><li><p>Cash</p><p> …</p></li><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=4137" target="_blank" rel="noopener">BZOJ 4137</a></p></li></ol></li></ol><h2 id="整体二分"><a href="#整体二分" class="headerlink" title="整体二分"></a>整体二分</h2><ol><li><p>条件:</p><ol><li><p>答案具有二分性</p></li><li><p>修改独立,修改对询问独立</p></li><li><p>离线算法</p></li></ol></li><li><p>形如: $ solve(l,r,S) $</p></li><li><p>例题:</p><ol><li><p>静态区间第K小 <del>(主席树)</del></p></li><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=3110" target="_blank" rel="noopener">BZOJ 3110</a></p><ol><li><p>线段树套平衡树 <del>(愚蠢的做法)</del></p></li><li><p>权值线段树套线段树</p></li><li><p>整体二分</p></li></ol></li><li><p><a href="http://www.lydsy.com/JudgeOnline/problem.php?id=2527" target="_blank" rel="noopener">BZOJ 2527</a></p></li></ol></li></ol><h2 id="Meet-in-the-middle"><a href="#Meet-in-the-middle" class="headerlink" title="Meet in the middle"></a>Meet in the middle</h2><ol><li><p><del>其实就是双向搜索</del></p></li><li><p>例题</p><ol><li><p>给出一个DAG,求一个点A到另一个点B路径长度为L的方案数</p><ol><li><p>求出从A和B出发的距离为 L/2 的点及其方案数</p></li><li><p>ans=集合交集乘积的和</p></li></ol></li><li><p>ABCDEF</p></li><li><p>A</p></li></ol></li></ol>]]></content>
<categories>
<category> 笔记 </category>
</categories>
<tags>
<tag> CDQ分治 </tag>
<tag> 整体二分 </tag>
</tags>
</entry>
</search>