-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
104 lines (56 loc) · 40 KB
/
atom.xml
File metadata and controls
104 lines (56 loc) · 40 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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>mayiyang</title>
<subtitle>keep solving</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://wlmayiyang.github.io/"/>
<updated>2021-12-29T12:52:50.868Z</updated>
<id>http://wlmayiyang.github.io/</id>
<author>
<name>mayiyang</name>
</author>
<generator uri="https://hexo.io/">Hexo</generator>
<entry>
<title>网络流基础</title>
<link href="http://wlmayiyang.github.io/2021/12/29/flow-basic/"/>
<id>http://wlmayiyang.github.io/2021/12/29/flow-basic/</id>
<published>2021-12-29T12:39:02.000Z</published>
<updated>2021-12-29T12:52:50.868Z</updated>
<content type="html"><![CDATA[<h2 id="相关概念"><a href="#相关概念" class="headerlink" title="相关概念"></a><strong>相关概念</strong></h2><p>$V$ 表示所有结点的集合<br>$E$ 表示所有边的集合<br>$G=(V,E)$ ,表示整个图<br>$s$ 表示源点,$t$ 表示汇点<br>每条边 $(u,v)$ ,有容量 $c(u,v)$($c(u,v)\geq0$),流量 $f(u,v)$<br>$c(u,v)=0$ 则表示$(u,v)$不在网络中<br><strong>三个性质</strong></p><ol><li><strong>容量限制</strong> $f(u,v)\leq c(u,v)$</li><li><strong>反对称性</strong> $f(u,v)=-f(v,u)$</li><li><strong>流量平衡</strong> $\sum_{u\in V} f(v,u)=0$</li></ol><h2 id="最大流"><a href="#最大流" class="headerlink" title="最大流"></a><strong>最大流</strong></h2><p><strong>流量</strong>: $|f|=\sum_{v\in V}f(s,v)$</p><p><strong>最大流</strong>: 在满足网络流三条性质时,$|f|$的最大值</p><p><strong>残量网络</strong>(也就是一条弧还能有多少流量经过</p><p><strong>残量网络</strong> $G_f$(如果网络中一条边 $cap = 0$,认为不在残量网络中) </p><p><strong>残量网络边集</strong> $E_f$</p><p><strong>后向弧</strong>(实现时常用$i \oplus 1$):使得操作可以反悔</p><p><strong>增广路</strong>: 在残量网络中一条s通往t的路径,其中任意一条弧都有 $r(u,v)>0$</p><p><strong>增广路算法</strong>: 每次找一条最短的增广路径,然后沿着路径修改流量,无增广路时,流为最大流。</p><p>下面把 $f,r,c$ 的定义域扩展为点集 $f(X,Y)=\sum_{x\in X} \sum_{y\in Y} f(x,y) $</p><h2 id="割"><a href="#割" class="headerlink" title="割"></a><strong>割</strong></h2><p><strong>定义</strong>: $S+T=V,s\in S,t\in T$</p><p><strong>注意</strong>: 使用割做题时,不要认为 $S$ 或 $T$ 需要联通。</p><p><strong>一些结论</strong></p><ol><li><blockquote><p>$f(X,X)=0$<br>$f(X,Y) = -f(Y,X)$<br>$F(X \bigcup Y,Z)=f(X,Z)+f(Y,Z)$<br>$F(X,Y \bigcup Z)=F(X,Y)+F(X,Z)$</p></blockquote></li><li><p>不包含s和t的点集,与它相关联的边上的流量值和为 0</p><blockquote><p>$f(X,V)=\sum_{x\in X}(\sum_{v\in V} f(x,v))=\sum_{x\in X}0 = 0$</p></blockquote></li><li><p><strong>任何割的流量等于整个网络的流量</strong></p><blockquote><p>$f(S,T)=f(S,V)-f(S,S)=f(s,V)+f(S-s,V)=|f|$</p></blockquote></li><li><p>任何割的容量大于等于整个网络的流量 $|f| \leq c(S,T)$</p><blockquote><p>$f(S,T)=\sum_{x\in S}\sum_{y\in T} f(x,y) \leq\sum_{x\in S}\sum_{y\in T} c(x,y)=c(S,T)$</p></blockquote></li></ol><p><strong>最小割</strong>: 所有可能的割中,容量最小的割<br><strong>最大流最小割定理</strong>:<br>对于一个网络流图 $G=(V,E)$,其中有源点 $s$ 和汇点 $t$,下面三个条件是等价的:</p><ol><li>流 $f$ 是图 $G$ 的最大流</li><li>残量网络不存在增广路</li><li>对于 $G$ 的某一个割 $(S,T)$,此时 $f = C(S,T)$</li></ol><p>$1 \rightarrow 2$: 根据网络流算法过程易得。</p><p>$3 \rightarrow 1$: 由上述结论 $4$ ,任何总流量不超过最小割容量,$f$ 必为最大流。</p><p>$2 \rightarrow 3$: <strong>残量网络不存在增广路</strong>,定义 $S$ 为当前残量网络中 $s$ 能够到达的点,$T = V - S$ 。$(S, T)$ 显然为割。</p><p>$\forall u \in S,v \in T$,有 $f(u,v)=c(u,v)$ 。所以 $f(S,T)=\sum f(u,v)=\sum c(u,v)=C(S,T)$ 。</p><h2 id="最小费用最大流"><a href="#最小费用最大流" class="headerlink" title="最小费用最大流"></a><strong>最小费用最大流</strong></h2><h2 id="无源汇上下界可行流"><a href="#无源汇上下界可行流" class="headerlink" title="无源汇上下界可行流"></a><strong>无源汇上下界可行流</strong></h2><p>可行流:满足上下界和流量守恒<br><strong>核心思路: 在可行流上增流调整</strong>。<br>建图,源点为 $S$ ,汇点为 $T$ 。<br>对于原图中每条边 $u\rightarrow v$,新图建 $u \rightarrow v$ 流量为 $high - low$。<br>记 <script type="math/tex">g(x) = \sum_{to_i = x} low_i - \sum_{from_i = x} low_i</script><br>$g(x) > 0$ 时,$S \rightarrow x$ 流量 $g(x)$;<br>$g(x) < 0$ 时,$x \rightarrow T$ 流量 $-g(x)$。<br>新连的<strong>附加边全部流满</strong>才为可行</p><h2 id="有源汇上下界可行流"><a href="#有源汇上下界可行流" class="headerlink" title="有源汇上下界可行流"></a><strong>有源汇上下界可行流</strong></h2><p>思想同上,只是还要 $T \rightarrow S$ 上下界 $[0, +\infty]$ 的边。</p><h2 id="有源汇上下界最大流"><a href="#有源汇上下界最大流" class="headerlink" title="有源汇上下界最大流"></a><strong>有源汇上下界最大流</strong></h2><ol><li>先跑出可行流,摘除 $T \rightarrow S$ 的边,此时满足有源汇流量守恒。</li><li>残量网络上跑出最大流,与附加流合并即可求得。</li></ol><h2 id="有源汇上下界最小流"><a href="#有源汇上下界最小流" class="headerlink" title="有源汇上下界最小流"></a><strong>有源汇上下界最小流</strong></h2><ol><li>先跑出可行流,摘除 $T \rightarrow S$ 的边,此时满足有源汇流量守恒。</li><li>在附加流的基础上,减去 $dinic(T, S)$ 的结果。本质上是退流。</li></ol><h2 id="有源汇上下界最小费用可行流"><a href="#有源汇上下界最小费用可行流" class="headerlink" title="有源汇上下界最小费用可行流"></a><strong>有源汇上下界最小费用可行流</strong></h2><p>建图方式与有源汇上下界可行流基本相同,只是原始边加上费用。</p>]]></content>
<summary type="html">
<h2 id="相关概念"><a href="#相关概念" class="headerlink" title="相关概念"></a><strong>相关概念</strong></h2><p>$V$ 表示所有结点的集合<br>$E$ 表示所有边的集合<br>$G=(V,E)$ ,表
</summary>
<category term="algorithm" scheme="http://wlmayiyang.github.io/categories/algorithm/"/>
<category term="flow" scheme="http://wlmayiyang.github.io/categories/algorithm/flow/"/>
<category term="basic" scheme="http://wlmayiyang.github.io/categories/algorithm/flow/basic/"/>
<category term="algorithm" scheme="http://wlmayiyang.github.io/tags/algorithm/"/>
<category term="flow" scheme="http://wlmayiyang.github.io/tags/flow/"/>
</entry>
<entry>
<title>Hello World</title>
<link href="http://wlmayiyang.github.io/2020/12/27/hello-world/"/>
<id>http://wlmayiyang.github.io/2020/12/27/hello-world/</id>
<published>2020-12-27T05:03:39.472Z</published>
<updated>2020-12-27T05:03:39.468Z</updated>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p><h2 id="Hello"><a href="#Hello" class="headerlink" title="Hello!"></a>Hello!</h2><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><pre><code class="lang-bash">$ hexo new "My New Post"</code></pre><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><pre><code class="lang-bash">$ hexo server</code></pre><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><pre><code class="lang-bash">$ hexo generate</code></pre><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><pre><code class="lang-bash">$ hexo deploy</code></pre><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html" target="_blank" rel="noopener">Deployment</a></p>]]></content>
<summary type="html">
<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.
</summary>
</entry>
<entry>
<title>codeforces</title>
<link href="http://wlmayiyang.github.io/2019/12/07/codeforces/"/>
<id>http://wlmayiyang.github.io/2019/12/07/codeforces/</id>
<published>2019-12-07T13:13:59.000Z</published>
<updated>2021-12-29T12:36:36.095Z</updated>
<content type="html"><![CDATA[<hr><h1 id="codeforces566C"><a href="#codeforces566C" class="headerlink" title="codeforces566C"></a><a href="http://codeforces.com/problemset/problem/566/C" target="_blank" rel="noopener">codeforces566C</a></h1><h2 id="description"><a href="#description" class="headerlink" title="description"></a><strong>description</strong></h2><ul><li>$n$个点的树,点有点权,边有边权,定义树上两点距离$dis(u,v)=( \sum_{e\in path(u, v)}w_e)^{1.5}$,求带权中心位置</li><li>$n\leq 100000$</li></ul><h2 id="solution"><a href="#solution" class="headerlink" title="solution"></a><strong>solution</strong></h2><ul><li>直接维护显然不行,考虑带权重心能否从$u$移动到$v$<br><img src="https://i.loli.net/2021/08/21/W7hzZPHLNu6BYrK.png" alt="1.png"><br>但是直接比较$u$, $v$答案不弱于原题,先做出带权重心可以在边上某处的假设,设$u$与带权重心距离$x$<script type="math/tex; mode=display">f(x)=\sum_{i \in A}a_i(d_i+x)^{1.5}+\sum_{i \in B}a_i(d_i+l-x) ^ {1.5}</script>有上述假设后$f$是连续函数,$f’’(x)>0$,函数是凸函数,只有一个最低点,<br>所以$f’(0)>=0$时,$u\rightarrow v$必然不优<script type="math/tex; mode=display">\begin{aligned}f'(0)&=f'(x)|_{x=0}\\&=1.5[\sum_{i \in A}a_i(d_i+x)^{0.5}-\sum_{i \in B}a_i(d_i+l-x) ^ {0.5}]|_{x=0}\\&=1.5[\sum_{i\in A}^na_idis(u, i)^{0.5}-\sum_{i\notin A}^na_idis(u, i)^{0.5}]\end{aligned}</script>以$u$作为根,记$sum_x=\sum_{i\in subtree(x)}a_id_i^{0.5}$, 满足$f’(0)<0$的$v$即为$u$儿子$sum$的绝对众数,至多一个<br>至此,做法仍为$O(n^2)$,但移动方向唯一很有启发<br>考虑点分治,分治层数最多$\log n$,向子树<strong>移动方向唯一</strong>,只需关心点分树的一条链,那么总共只有$O(\log n)$个点需要计算,总复杂度$O(n\log n)$<br>树上最值的一些问题,一条路是大力维护,还有一条是<strong>对可选点进行比较,不断向更优位置靠近</strong>,像本题是从带权重心向四周答案不断增大的结构。本题中化离散为连续的思想也值得借鉴</li></ul><hr><h1 id="codeforces566E"><a href="#codeforces566E" class="headerlink" title="codeforces566E"></a><a href="http://codeforces.com/problemset/problem/566/E" target="_blank" rel="noopener">codeforces566E</a></h1><h2 id="description-1"><a href="#description-1" class="headerlink" title="description"></a><strong>description</strong></h2><ul><li>$n$个点的树,已知与每个点$u$相距不超过2的点集$S_u$,但是$\{S\}$乱序给出,恢复这棵树(答案不唯一任取)</li><li>$n\leq 1000$</li></ul><h2 id="solution-1"><a href="#solution-1" class="headerlink" title="solution"></a><strong>solution</strong></h2><ul><li>第一种想法是从叶子开始向上删点,但集合乱序挺恶心<br>换个角度,试图分析点集性质。</li></ul><p><strong>part1</strong></p><ul><li>把$S_x$中的元素提取出来,会发现$x$的爷爷只与$x$父亲相连<br><img src="https://i.loli.net/2021/08/20/HJSWTofKsLh7pFi.png" alt="1.png"><br>根据上图,选择红点与绿点,两集合交集大小为2,在交集元素间连边<br>通过判断两两集合交集为2,可以连上所有不挂叶子的边。</li></ul><p><strong>part2(接叶子)</strong></p><ul><li>考虑叶子$u$,包含$u$的集合中大小最小的必定为$S_u$<br>根据$S_u$将叶子划成若干子集<br>每个子集互为兄弟,分别考虑。<br>为方便,记$adj_u$为$u$和与直接有边相连<br>若有叶子$u_1, u_2, \cdots, u_p$,记$F = fa_{u_1}$, 容易发现<br>$S_{u_1}$包括$adj_F$,以及这些叶子<br>而$adj_u$在非叶节点大于两个时两两不同,可以唯一区分</li></ul><p><strong>part3</strong></p><ul><li>还要注意,非叶节点不超过两个还需要特判</li></ul><hr><h1 id="codeforces585C"><a href="#codeforces585C" class="headerlink" title="codeforces585C"></a><a href="http://codeforces.com/problemset/problem/585/C" target="_blank" rel="noopener">codeforces585C</a></h1><h2 id="description-2"><a href="#description-2" class="headerlink" title="description"></a><strong>description</strong></h2><p>$a=1,b=1$,构造一个AB字符串,遇到A执行$b=a+b$,遇到B执行$a=a+b$<br>要求最终$a=x ,b=y$<br><strong>data limit</strong> $x,y\leq 1e18$</p><h2 id="solution-2"><a href="#solution-2" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>从终态逆推,容易发现是在执行辗转相减,运用辗转相除求gcd的过程加速辗转相减<br>注意$\gcd(x,y) > 1$是无解</p><hr><h1 id="codeforces585E"><a href="#codeforces585E" class="headerlink" title="codeforces585E"></a><a href="http://codeforces.com/problemset/problem/585/E" target="_blank" rel="noopener">codeforces585E</a></h1><h2 id="description-3"><a href="#description-3" class="headerlink" title="description"></a><strong>description</strong></h2><blockquote><p>有n个数,可以从中任意选取一个x,然后可以从剩下的数中选取任意个构成一个集合S,使集合S中所有数的$gcd(S)>1$,且$gcd(gcd(S),x)=1$,求方案数。</p></blockquote><h2 id="solution-3"><a href="#solution-3" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>先用$tmp[i]$表示$i$的倍数有几个,<br>对于每个质数$x$,选出$x$的倍数(共$tmp[x]$个),会对答案贡献$(n-tmp[x])*(2^{tmp[x]}-1)$<br>此时考虑$prime1\ast prime2$,在枚举$prime1,prime2$时都计算到,需要$ans-=(n-tmp[x])\ast (2^{tmp[x]}-1)$;<br>类似的,三个质数乘积$p\ast q\ast r$,在$p,q,r$分别加一次,$p\ast q$,$p\ast r$,$q\ast r$分别减一次,因此还要加一遍<br>若一个质因子$p$出现两遍,要么在$p$中算过,要么$gcd!=1$,因此对答案没有贡献<br>容易发现,容斥系数恰好为$-mu[x]$<br>暴枚$i$,$ans=\sum_{i}(-mu[i])\ast(2^{tmp[i]}-1)\ast(n-tmp[i])$</p><hr><h1 id="codeforces773D"><a href="#codeforces773D" class="headerlink" title="codeforces773D"></a><a href="http://codeforces.com/problemset/problem/773/D" target="_blank" rel="noopener">codeforces773D</a></h1><h2 id="description-4"><a href="#description-4" class="headerlink" title="description"></a><strong>description</strong></h2><p>给一个完全图,边有边权,求以每个点为根的内向树,使所有点到该点的距离和最小,注意,距离定义为两点之间路径边权的最小值<br>$n\leq 2000$</p><h2 id="solution-4"><a href="#solution-4" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>先要充分挖掘这棵内向树的性质:<br>如果存在$y-x$和$z-x$两条边,把$z-x$变为$z-y$一定<strong>不会变劣</strong>,因此,<strong>每个点最多一条入边</strong>,也就是说,这是<strong>一条链</strong><br>不妨设最优的链由根开始的权值为$w_1,w_2,w_3,\cdots,w_{n-1}$,则有$ans=\sum_{i=1}^{n-1}\min_{j=1}^iw_i$<br>这样仍旧不好处理,有一步重要的转化:设所有边权值最小为$M$,把每条边减去$M$,答案加上$M(n-1)$,此时,必有一条边<strong>权值为零</strong>,只要途经这条边,后面的值均是零<br>不妨设链上最靠前的零边为$w_k$,经过画图会发现,$\forall i\leq k-3,w_i>w_{i+1}$,下面简单证一下:<br>假设存在$w_i\leq w_{i+1}$,那么可以把$e_{i+1}$直接连向$0$边一端,再从零边另一端走出,结果不劣,附图说明:<a href="https://imgchr.com/i/BLiOQf" target="_blank" rel="noopener"><img src="https://s1.ax1x.com/2020/11/10/BLiOQf.png" alt="BLiOQf.png"></a><br>然后路径只有两种,要么由根通往$0$边某端点的路径长度,要么允许$2w$的代价瞬移至零边端点,直接对于每个点跑dij,获得$O(n^3)$的复杂度<br>改成$O(n^2)$就差一步,只需把<strong>$dis_i$初始化成最小出边的两倍</strong>,直接跑dij即可(等于说是<strong>多加入一个源点进行一轮扩展</strong>)</p><hr><h1 id="codeforces1243D"><a href="#codeforces1243D" class="headerlink" title="codeforces1243D"></a><a href="http://codeforces.com/problemset/problem/1243/D" target="_blank" rel="noopener">codeforces1243D</a></h1><h2 id="description-5"><a href="#description-5" class="headerlink" title="description"></a><strong>description</strong></h2><p>$n$个点的完全无向图,$m$条边边权为1,其余边权为0,求最小生成树<br>$n,m\leq 10^5$</p><h2 id="solution-5"><a href="#solution-5" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>容易得到答案为补图的联通块个数,运用链表+bfs解决<br>每次选取一个未分配的点,从这个点 bfs。链表中存储没访问的点<br>假设当前点是 u ,如果原图上有边 $u \rightarrow v$,就把点 v 标记($cover[v]=1$)。从链表头遍历,对于$cover[v]=0$的点,塞入队列,并从链表中删除。<br>注意还要把标记取消!!!<br>因为每个点和每条边都只会走一次,复杂度是$O(n+m)$ 。</p><hr><h1 id="codeforces1247E"><a href="#codeforces1247E" class="headerlink" title="codeforces1247E"></a><a href="http://codeforces.com/problemset/problem/1247/E" target="_blank" rel="noopener">codeforces1247E</a></h1><h2 id="description-6"><a href="#description-6" class="headerlink" title="description"></a><strong>description</strong></h2><p>一个n*m的矩阵,有个别位置会有石头,石头受到撞击会沿着方向撞到墙为止(每个石头会占一个格子)。你从左上角出发,只能向右或者向下走,问你走到右下角的方案数。</p><h2 id="solution-6"><a href="#solution-6" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>先统计每个位置右边,下边有几个石头,存在$row$与$col$中<br>考虑动态规划,$dp[i][j][0]$表示从$(i,j)$出发向右移动至终点的方案数,$dp[i][j][1]$表示从$(i,j)$出发向下移动至终点的方案数。考虑向右移动时,最远可以移到$(i,m-row[i][j+1])$,<script type="math/tex">dp[i][j][0]=\sum_{p=j+1}^{m-row[i][j+1]}dp[i][p][1]</script><br>同理 <script type="math/tex">dp[i][j][1]=\sum_{p=i+1}^{n-col[i+1][j]}dp[p][j][0]</script><br>运用前缀和优化$dp$即可<br>时间复杂度$O(n^2)$</p><hr><h1 id="codeforces1284D"><a href="#codeforces1284D" class="headerlink" title="codeforces1284D"></a><a href="http://codeforces.com/problemset/problem/1284/D" target="_blank" rel="noopener">codeforces1284D</a></h1><h2 id="description-7"><a href="#description-7" class="headerlink" title="description"></a><strong>description</strong></h2><p>线段集合$A,B$分别含有$n$条线段,若存在$A_i$与$A_j$相交,但$B_i$与$B_j$不相交,输出no</p><h2 id="solution-7"><a href="#solution-7" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>与<a href="http://codeforces.com/problemset/problem/1106/E" target="_blank" rel="noopener">cf1106E</a>预处理做法相似,类似于扫描线<br>对于每一段线段:<br>1.在 $tim=sa_i$ 处插入 $[sb_i,eb_i]$,并加入$insert$标记(即$typ=1$)<br>2.在 $tim=ea_i+1$ 处删除 $[sb_i,eb_i]$,并加入$remove$标记(即$typ=-1$)<br>把上述$2<em>n$个事件按$tim$排序<br><strong>attention:当 $tim$ 相等时,先删除区间,再加入新的区间!!!</strong><br>这样的话,对于每个时间点$tim$,能够维护哪些$A$线段会覆盖$tim$。显然,这些$A$线段两两相交,因此,对应的$B$线段也必须两两相交。(<em>*核心</em></em>)<br>区间$[a,b]$ 与 $[c,d]$不相交,当且仅当 $b<c$ 或 $d<a$ 。</p><p>若 $ea_i < \max(sb)$ 或 $sa_i > \min(eb)$ ,则新加入的线段不满足两两相交<br>上述信息只需要维护两个$multiset$,一个维护插入的区间左端点$sb$,另一个维护插入的区间的右端点$eb$<br>上述过程仅仅考虑$A$线段相交,$B$线段不相交,还需要交换$A$,$B$后再来一次</p><hr><h1 id="codeforces1363F"><a href="#codeforces1363F" class="headerlink" title="codeforces1363F"></a><a href="http://codeforces.com/problemset/problem/1363/F" target="_blank" rel="noopener">codeforces1363F</a></h1><h2 id="description-8"><a href="#description-8" class="headerlink" title="description"></a><strong>description</strong></h2><p>给出长为n的字符串s与t,一次操作可以把s中的一个字符取出,并放置到原位置之前,试求把s变成t的最小步数</p><h2 id="solution1"><a href="#solution1" class="headerlink" title="solution1"></a><strong>solution1</strong></h2><p> 考虑动态规划,$dp[i][j]$表示$S$中的$i$个字符与$T$中$j$个字符匹配(其中一个是另一个的后缀)的最小步数<br> 边界是$dp[i][0]=0$<br> 考虑转移过程:<br> 1.丢弃S中的第$i$个字符(<strong>不是下标为i</strong>),之后再用一步匹配该位置,$dp[i][j]=dp[i-1][j]+1$<br> 2.$s[i]==t[j]$时,无需操作,$dp[i][j]=dp[i-1][j-1]$<br> 3.$dp[i][j]=dp[i][j-1]$,但是想要如此转移有一个先决条件,<strong>$S$中剩下的字符中$t[j]$的个数必须比$T$中剩下的字符中$t[j]$的个数多</strong>,若在预处理阶段处理$suf[i][j]$表示$j+1—n$中字符$i$的个数,$suf_s[t[j]][i+1]>suf_t[t[j]][j+1]$<br> 推荐用记忆化实现<br> 时间复杂度$O(n^2)$</p><h2 id="solution2"><a href="#solution2" class="headerlink" title="solution2"></a><strong>solution2</strong></h2><p> 联想到$LCS$的求解<br> 最初感觉$answer=n-LCS(s,t)$,但是马上会有反例:$S=abb,T=bba$,答案应为$2$<br> 考虑题目限制条件,字符只能从后面移动到前面,对于$S_{i+1 \sim n}$与$T_{j+1 \sim n}$,一旦S中某个字符比T少,就无法匹配<br> $dp[i][j]=\max(dp[i-1][j],dp[i][j-1])$不受影响<br> 转移$dp[i][j]=(dp[i-1][j-1]+1)*[s[i]=t[j]]$时必须先满足$\forall k, suf[k][i+1]\geq suf[k][j+1]$<br> 时间复杂度$O(n^2)$ </p><hr><h1 id="codeforces1373F"><a href="#codeforces1373F" class="headerlink" title="codeforces1373F"></a><a href="http://codeforces.com/problemset/problem/1373/F" target="_blank" rel="noopener">codeforces1373F</a></h1><h2 id="description-9"><a href="#description-9" class="headerlink" title="description"></a><strong>description</strong></h2><p>有$n$个壶,$n$个桶,第$i$个桶可以往第$i$个壶与第$i+1$个壶里倒水(特殊的,$n$号桶可以往第1个壶内倒水),问能否灌满所有壶</p><h2 id="solution-8"><a href="#solution-8" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>首先,记1号桶往1号壶内倒入的水量为$S$,如果知道$S$,显然可以再$O(n)$时间内判断是否可行<br>会发现如果$1$号桶往$1$号壶倒的水过多,可能导致后面的壶倒不满了,此时需要调少该水量<br>否则,可以调高该水量<br>上述两行发现,$S$对答案的影响是单调的,可以二分实现<br>注意二分上下界不要写错<br>时间复杂度$O(nlogn)$</p><hr><h1 id="codeforces1086D"><a href="#codeforces1086D" class="headerlink" title="codeforces1086D"></a><a href="http://codeforces.com/problemset/problem/1086/D" target="_blank" rel="noopener">codeforces1086D</a></h1><h2 id="description-10"><a href="#description-10" class="headerlink" title="description"></a><strong>description</strong></h2><p>$n$个人拍成一排玩石头剪刀布,初始给定每个人的手势。进行$q$次询问,每次询问修改一个人的手势,查询有多少人可能获胜。比赛规则是进行$n-1$轮,每一轮由你指定相邻两人比拼,输者淘汰,若平局,由你指定一人淘汰。</p><h2 id="solution-9"><a href="#solution-9" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>一、手势唯一时,答案为$n$<br>二、手势种类为两种时,答案为获胜的手势个数<br>三、手势有三种时,分别考虑每一种,记种类编号为$x$,$x$可以胜过$y$,但不能胜过$z$<br>要使$x$能获胜,他的左右两侧分别至少出现一个$y$($y$一定胜过$z$,$x$可以两两对峙)<br>具体实现用了三个$set$存不同手势,并用树状数组记录三种手势的位置。<br>记$yl$为最左侧的$y$,$yr$为最右侧的$y$,记$zl$为最左侧的$z$,$zr$为最右侧的$z$<br>如果$zl<yl$,则$ans-=query(x,yl)-query(x-zl)$<br>如果$yr<zr$,则$ans-=query(x,zr)-query(z,yr)$</p><hr><h1 id="codeforces1237E"><a href="#codeforces1237E" class="headerlink" title="codeforces1237E"></a><a href="http://codeforces.com/problemset/problem/1237/E" target="_blank" rel="noopener">codeforces1237E</a></h1><h2 id="description-11"><a href="#description-11" class="headerlink" title="description"></a><strong>description</strong></h2><p> 询问$n$个点的符合以下要求的二叉搜索树有几个:每个点上标$1-n$的数字,互不重复,每个点左儿子的奇偶性与之相异,右儿子的奇偶性与之相同,且只有最后一层不满。<br> $n \leq 10 ^ 6$</p><h2 id="solution-10"><a href="#solution-10" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>首先,仅有最后一层不满,必定为满二叉树上加若干条边得到。<br>其次,考虑$x$是$y$的左儿子,$x\rightarrow r\rightarrow y$,由于奇偶性不同,$size(rson(x))\mod 2=0$<br><img src="https://i.loli.net/2020/09/12/FGIp8h9Q6iuzxSE.png" alt="graph.png"><br>然后,考虑$x$是$y$的右儿子,$y\rightarrow l\rightarrow x$,由于奇偶性相同,$size(lson(x))\mod 2=1$<br><img src="https://i.loli.net/2020/09/12/cEOIwpgMRaPBxdJ.png" alt="graph.png"><br>总结一下,若一个点$x$是左儿子,$size(rson(x))\mod 2=0$,否则$size(lson(x))\mod2=1$<br>所以,满二叉树的最后一层节点要么是叶子,要么只有左儿子。<br>然后会有一个朴素的算法:由底到顶考虑满二叉树中的节点,根据上述总结判断,若不满足,答案自增,该点到根的路径上所有点的$size$自增,时间复杂度$O(nlogn)$。容易发现,只用保存$size\mod2$,自增改为$xor 1$即可,会发现答案只有$0$或$1$。<br>通过<del>模拟</del>思考发现,遍历完最后一层节点后,倒数第二层$size%2$均为$0$,其余不变<br>记$a[x]$为在$dep=x$的满二叉树上加几条边才能满足条件,$a[1]=1,a[2]=1,a[3]=2$<br>对于$i>3$,有$a[i]=a[i-2]+2^{i-2}$,递推即可,当且仅当$n=dep+a[dep]\ $或$\ n=dep+a[dep]+1$时,$ans=1$</p><hr><h1 id="codeforces1237F"><a href="#codeforces1237F" class="headerlink" title="codeforces1237F"></a><a href="http://codeforces.com/problemset/problem/1237/F" target="_blank" rel="noopener">codeforces1237F</a></h1><h2 id="description-12"><a href="#description-12" class="headerlink" title="description"></a><strong>description</strong></h2><p>一个$n*m$的网格,$ban$掉了若干行与若干列,问摆放任意多张$1\ast 2$的矩形,且每行每列中不存在两个格子属于不同的矩形的方案数,对$998244353$取模<br>$n\leq 3600$</p><h2 id="solution-11"><a href="#solution-11" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>很好的$dp$计数题。<br>首先考虑枚举横向的矩形个数$x$,与纵向的矩形个数$y$,则我们需要$x+y+y$个空行,且有$y$组连续的空行,列同理。这个东西似乎不好处理,但如果先考虑有$y$组连续的空行,剩下的$x$行仅仅是一个组合数而已。<br>定义$dp[x][y]$为考虑前$x$行,取了$y$组连续两个的空行的方案数,转移很方便:</p><script type="math/tex; mode=display">dp[x][y]=dp[x-1][y]</script><script type="math/tex; mode=display">dp[x][y]+=dp[x-2][y-1]*[!ban[x]\ \wedge \ !ban[x-1]\ \wedge x>=2\ \wedge y>=1]</script><p>再定义$dp_{row}[x][y]$为$y$组连续两个的空行,$x$个空行的方案数:</p><script type="math/tex; mode=display">dp_{row}[x][y]=dp[n][y]*\binom{n-ban-y-y}{x}</script><p>列同理<br>统计答案时,横向矩形之间可以交换位置,方案数为$x!$</p><script type="math/tex; mode=display">ans=\sum_{x=0}^{n/2}\sum_{y=0}^{m/2}dp_{row}[x][y]*dp_{col}[y][x]*x!*y!</script><hr><h1 id="codeforces1086F"><a href="#codeforces1086F" class="headerlink" title="codeforces1086F"></a><a href="https://codeforces.com/problemset/1086/F" target="_blank" rel="noopener">codeforces1086F</a></h1><h2 id="description-13"><a href="#description-13" class="headerlink" title="description"></a><strong>description</strong></h2><p>有$n$个着火点,每一秒与已着火的点八连通的点会着火,着火持续$t$秒,求$\sum_x\sum_ytim(x,y)$,其中$tim(x,y)$指$(x,y)$着火的时间,若$(x,y)$未着火则$tim(x,y)=0$<br>$n\leq50\ \ |x|\leq 1e8$</p><h2 id="solution-12"><a href="#solution-12" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>首先考虑暴力算法。会发现计算第$x$秒有几个新着火点不太容易,但计算截止第$x$秒全部着火的点相对容易得多,我们记$f(x)$为前$x$秒的着火点数量,边界$f(0)=n$,如果计算单个$x$的函数值,可以把若干个边长为$x+x+1$的正方形做面积并,这样的问题可以用扫描线解决(甚至不必写线段树,直接写$O(n^2)$暴力即可)<br>考虑计算答案,答案<script type="math/tex">ans=(t+1)f(t)-\sum_{i=1}^tf(i)</script><br>迄今为止,得到了$O(tn^2)$的算法,着重考虑少计算一些$f$值。<br>$f$值想必会有一点特殊性质,从最特殊的情况着手,考虑$n=1$,这时$f(x)=(2x+1)^2$,是一个二次函数,会不会$f$是一个二次函数?<br>这句话有一定道理,但存在漏洞,应该是一个分段二次函数,这样考虑该结论的正确性:<br>每轮变化相当于在图形外表面再<strong>镶上一圈</strong>,<strong>在正方形相交情况不改变时,呈现的就是二次函数</strong>,现在只用找出所有相交点,具体来说是$\lfloor\frac{x_i-x_j+1}{2}\rfloor$和$\lfloor\frac{y_i-y_j+1}{2}\rfloor$,一共有$O(n^2)$个<br><strong>$k+1$个不共线的点必能确定唯一的$k$次函数</strong>,由于每一段是二次函数,去每一段的前三对数,运用拉格朗日插值即可得到二次函数,运用平方和公式求部分和即可。<br>总时间复杂度$O(n^3\log n)-O(n^4)$(根据写法不同有差异)</p><hr><h1 id="codeforces1548C"><a href="#codeforces1548C" class="headerlink" title="codeforces1548C"></a><a href="https://codeforces.com/problemset/1548/C" target="_blank" rel="noopener">codeforces1548C</a></h1><h2 id="description-14"><a href="#description-14" class="headerlink" title="description"></a><strong>description</strong></h2><p>对于所有$1\leq x\leq3n$求出<script type="math/tex">\sum_{i=1}^n\binom{3i}{x}</script><br>$1\leq n \leq 10^6$</p><h2 id="solution1-1"><a href="#solution1-1" class="headerlink" title="solution1"></a><strong>solution1</strong></h2><p>尝试从$x-1$向$x$递推,记所求为$f_x$</p><script type="math/tex; mode=display">f_x=f_{x-1}+\sum_{i=1}^n\binom{3i-1}{x}</script><p>然后发现有新的式子,再设<script type="math/tex">g_x=\sum_{i=1}^n\binom{3i-1}{x}, h_x=\sum_{i=1}^n\binom{3i-2}{x}, d_x=\sum_{i=1}^n\binom{3i-3}{x}</script><br>则有</p><script type="math/tex; mode=display">f_x=f_{x-1}+g_{x}\\ g_x=g_{x-1}+h_{x}\\ h_x=h_{x-1}+d_{x}\\ d_x=f_x-\binom{3n}{x}</script><p>消去$d_x$后,发现三个方程线性相关,方程个数还不够<br>再观察上述定义,<script type="math/tex">f_x+g_x+h_x=\sum_{i=1}^{3n}\binom{i}{x}=\binom{3n+1}{x+1}</script><br>方程个数足够,直接解即可(本题卡常,不要傻乎乎套$cramer’s\ rule$)<br>上述解法关键在于大胆<strong>设出几种式子,寻找递推关系</strong>,并仔细分析<strong>式子之间的关系</strong>(最后的$f+g+h$考验全局意识)</p><h2 id="solution2-1"><a href="#solution2-1" class="headerlink" title="solution2"></a><strong>solution2</strong></h2><blockquote><p>考虑生成函数,所求即为<script type="math/tex">[x^d]\sum_{i=1}^n(1+x)^{3i}</script><br>补上常数项$1$,<script type="math/tex">f_d=[x^d]\sum_{i=0}^n(1+x)^{3i}=[x^d]\frac{1-(1+x)^{3n+3}}{1-(1+x)^3}</script><br>直接进行大除法,由于分母次数仅有三,除法的复杂度为$O(n)$<br>该解法指明<strong>正确分析特殊情况的算法复杂度</strong>的关键性,需要结合实际题目选择合适做法,不能够因为常规多项式除法是$O(n^2)$而不往该方向靠拢<br><strong>适度使用生成函数</strong>可能可以简化问题,但不能成为呆板的生成函数选手,一定要<strong>结合其他技巧使用</strong></p></blockquote><hr><h1 id="codeforces1548D1-2"><a href="#codeforces1548D1-2" class="headerlink" title="codeforces1548D1/2"></a><a href="https://codeforces.com/problemset/1548/D2" target="_blank" rel="noopener">codeforces1548D1/2</a></h1><h2 id="description-15"><a href="#description-15" class="headerlink" title="description"></a><strong>description</strong></h2><p>有$n$个点,保证无三点共线,求有多少个三角形,面积为正整数且内格点数目为奇数。<br>Easy : $\forall x, y \equiv 0 \mod 2$<br>$1\leq n\leq6000$</p><h2 id="solution-13"><a href="#solution-13" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>有面积,内格点的限制,很容易想到$pick$定理<br> 下述记$S$为面积,$B$为外格点,$I$为内格点,<script type="math/tex">2S=B+2I-2</script><br> 不妨$I=2k+1$,则$2S=4k+B$,那么$B$必为偶数,$2S\equiv B \ (\mod 4)$<br>一个向量穿过的格点数为$\gcd(x, y)$,$B = \gcd(x3-x1, y3-y1)+\gcd(x2-x1,y2-y1)+\gcd(x3-x2,y3-y2)$<br>先考虑Easy:<br>各点坐标偶数,$B$的表达式可知$B$必为偶数,且$B$的值只与$x \mod 4, y \mod 4$有关,略加分讨即可<br>Easy -> Hard,难点主要在:<br>1.$B$不仅与坐标模4相关,还与具体坐标相关(比如$\gcd(3, 9)=3, \gcd(3,1)=1$)<br>2.如果直接算面积,叉积完了还有绝对值,而$x\equiv|x| \ \mod 4$不一定成立<br>抓住$B$偶数的性质继续分析,三条边上点数为奇奇奇或偶偶奇,至少一边为奇数,那一条边上的<strong>两点横纵坐标奇偶性相同</strong></p><p>WLOG,这两点(P, Q)为$ee$,剩余的一个点为$ee/(eo/oe/oo)$。<br>模4意义下,$x_R-x_P=x_Q-x_P,y_R-y_P =y_R - y_Q$, 因此<strong>$2S$必为偶数</strong>,上面的难点2消除<br>难点1只需在枚举$R$点之外,多枚举$RP, RQ, PQ$边上的点数mod4<br>枚举时要注意枚举的两个元素在同一个桶里时答案增多$\binom{c}{2}$</p><p>有时限制条件很多,直接做不可行,可以考虑<strong>在状态中增加几维,多枚举一些限制条件</strong></p><hr><h1 id="codeforces1620F"><a href="#codeforces1620F" class="headerlink" title="codeforces1620F"></a><a href="https://codeforces.com/problemset/1620/F" target="_blank" rel="noopener">codeforces1620F</a></h1><h2 id="description-16"><a href="#description-16" class="headerlink" title="description"></a><strong>description</strong></h2><p>给定一个长度为 $n$ 的排列 $p_i$ , 可以使每个位置加负号或不加,构造任意一组解,使得 $p$ 的最长下降子序列不超过 $2$。<br>$n \leq 10 ^ 6$</p><h2 id="solution-14"><a href="#solution-14" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>记长度为 $2$ 的最长下降子序列末尾为 $y$,长度为 $1$ 的最长下降子序列末尾为 $x$<br>考虑新加入一个数 $z$</p><ol><li>$z > x$, $(x, y) \rightarrow (z, y)$</li><li>$z > y$, $(x, y) \rightarrow (x, z)$</li><li>$z < y$, 不合法<br>直接 dp 转移是 $O(n ^ 3)$。<br>考虑一个常见的优化,dp 数组不记 0/1,而是记录满足条件的最值。<br>在此处即为 $f_{i, x}$ 为 $y$ 的最小值,优化到平方。<br>还会发现,合法的 $z$ 一定会在结果中的 $x$ 处或 $y$ 处出现。<br>用一个布尔变量记录 $p_{i-1}$ 的出现位置,另一个布尔变量记录 $p_{i-1}$ 的符号,简单转移即可。<br>时间复杂度 $O(n)$。</li></ol><h2 id="reflection"><a href="#reflection" class="headerlink" title="reflection"></a><strong>reflection</strong></h2><ol><li><p>dp 中一个常见的优化,数组不用布尔,而是记录满足条件的最值,使状态蕴含信息增加。</p></li><li><p>dp 时要注意状态的特殊性质,例如本题 $p_{i-1}$ 一定出现在某个位置。</p></li></ol><hr><h1 id="codeforces1617E"><a href="#codeforces1617E" class="headerlink" title="codeforces1617E"></a><a href="https://codeforces.com/problemset/1617/E" target="_blank" rel="noopener">codeforces1617E</a></h1><h2 id="description-17"><a href="#description-17" class="headerlink" title="description"></a><strong>description</strong></h2><p>定义操作 $x$ 为选择一个 $k$ 满足 $2 ^ k \geq x$,把 $x$ 变成 $2 ^ k - x$<br>定义 $x$ 与 $y$ 的距离为最少操作 $x$ 次数使得 $x = y$<br>给定序列,求 $\max(dis(a_i, a_j))$<br>$n \leq 10 ^ 5$, $a_i \leq 10 ^ 9$</p><h2 id="solution-15"><a href="#solution-15" class="headerlink" title="solution"></a><strong>solution</strong></h2><p>首先考虑距离的计算。<br>在 $x$ 与 $2 ^ k - x$ 之间连边,通过小数据尝试,会发现这是一个树的结构,证明大致如下:<br>对于一个 $x$ ,它与比他小的数只有一条边,就是选出最小的 $k$ 进行操作,如果 $k’ > k$ 满足,$2 ^ {k’} \geq 2 ^ {k + 1} \gt 2x$, 矛盾。<br>$dis(x, y)$ 即是该树上两点距离。<br>还可以发现树上 $fa_x$ 的二进制最高位严格小于 $x$,树高只有 $\log n$。<br>于是可以枚举每个 $a_i$ 到根上的所有点,尝试作为 LCA,在其不同子树中找两个点。</p><h2 id="reflection-1"><a href="#reflection-1" class="headerlink" title="reflection"></a><strong>reflection</strong></h2><ol><li>和为二的次幂的数连边,构成一棵树。</li><li>一些与数的性质相关的变换、关系等,可以从图论的角度考虑问题,看看是否可以通过图论手段转化问题。</li></ol><hr>]]></content>
<summary type="html">
<hr>
<h1 id="codeforces566C"><a href="#codeforces566C" class="headerlink" title="codeforces566C"></a><a href="http://codeforces.com/problems
</summary>
<category term="题目" scheme="http://wlmayiyang.github.io/categories/%E9%A2%98%E7%9B%AE/"/>
<category term="cf" scheme="http://wlmayiyang.github.io/categories/%E9%A2%98%E7%9B%AE/cf/"/>
<category term="problems" scheme="http://wlmayiyang.github.io/tags/problems/"/>
<category term="cf" scheme="http://wlmayiyang.github.io/tags/cf/"/>
</entry>
</feed>