WC 2022 学习笔记

Day   1   2022.01.22 \texttt{Day 1 2022.01.22} Day 1 2022.01.22 开幕式,好耶!
开幕式


Day   2   2022.01.23 \texttt{Day 2 2022.01.23} Day 2 2022.01.23

上午

才知道课程都是二选一,选了个第二课堂听听。

前置
  1. 向量加减

{ p = ( x 1 , y 1 ) , q = ( x 2 , y 2 ) p + q = ( x 1 + x 2 , y 1 + y 2 ) p − q = ( x 1 − x 2 , y 1 − y 2 ) \begin{cases} p = (x_1,y_1),q = (x_2,y_2)\\ p + q = (x_1 + x_2,y_1 + y_2)\\ p - q = (x_1 - x_2,y_1 - y_2) \end{cases} p=(x1,y1),q=(x2,y2)p+q=(x1+x2,y1+y2)pq=(x1x2,y1y2)

  1. 向量点积【标量】

{ A B → ⋅ C D → = x 1 x 2 + y 1 y 2 A B → ⋅ C D → = ∣ A B ∣ ∣ C D ∣ cos ⁡ θ \begin{cases} \overrightarrow{AB} \cdot \overrightarrow{CD} = x_1x_2 + y_1y_2\\ \overrightarrow{AB} \cdot \overrightarrow{CD} = |AB||CD| \cos \theta \end{cases} {AB CD =x1x2+y1y2AB CD =AB∣∣CDcosθ

  1. 向量叉积【矢量】

{ A B → × C D → = x 1 y 2 − x 2 y 1 A B → × C D → = ∣ A B ∣ ∣ C D ∣ sin ⁡ θ \begin{cases} \overrightarrow{AB} \times \overrightarrow{CD} = x_1y_2 - x_2y_1\\ \overrightarrow{AB} \times \overrightarrow{CD} = |AB||CD|\sin \theta \end{cases} {AB ×CD =x1y2x2y1AB ×CD =AB∣∣CDsinθ

同时有 0 × a = a × 0 = a × a = 0 \bold{0} \times \bold{a} = \bold{a} \times \bold{0} = \bold{a} \times \bold{a} = \bold{0} 0×a=a×0=a×a=0

∣ a × b ∣ |\bold{a} \times \bold{b}| a×b 在数值上等于 a , b \bold{a},\bold{b} a,b 构成的平行四边形的面积。

  1. 向量旋转

a = ( x , y ) \bold{a} = (x,y) a=(x,y),逆时针旋转 θ \theta θ 后为 a ′ = ( x cos ⁡ θ − y sin ⁡ θ , x sin ⁡ θ + y cos ⁡ θ ) \bold{a'} = (x \cos \theta - y \sin \theta,x \sin \theta + y\cos \theta) a=(xcosθysinθ,xsinθ+ycosθ)

  1. 多边形面积

S = 1 2 ∣ ∑ i = 1 n V i × V i m o d    n + 1 ∣ S = \frac{1}{2}|\sum_{i = 1}^{n} V_i \times V_i \mod n + 1| S=21i=1nVi×Vimodn+1∣

  1. 极坐标与极坐标系

  2. 误差判断

double eps = 1e-8;
return (x > eps) - (x < eps);
距离
  1. 欧式距离

二维 ∣ A B ∣ = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 |AB| = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} AB=(x2x1)2+(y2y1)2

三维 ∣ A B ∣ = ( x 2 − x 1 ) 2 + ( y 2 − y 1 ) 2 + ( z 2 − z 1 ) 2 |AB| = \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2 + (z_2 - z_1)^2} AB=(x2x1)2+(y2y1)2+(z2z1)2

  1. 曼哈顿距离

d ( A , B ) = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ d(A,B) = |x_1 - x_2| + |y_1 - y_2| d(A,B)=x1x2+y1y2

  1. 切比雪夫距离

d ( A , B ) = max ⁡ ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ∣ ) d(A,B) = \max (|x_1 - x_2|,|y_1 - y_2|) d(A,B)=max(x1x2,y1y2)

  1. 曼哈顿距离与切比雪夫距离的联系

曼哈顿距离 → \to 切比雪夫距离: ( x , y ) → ( x + y , x − y ) (x,y) \to (x + y,x - y) (x,y)(x+y,xy)

切比雪夫距离 → \to 曼哈顿距离: ( x , y ) → ( x + y 2 , x − y 2 ) (x,y) \to (\dfrac{x + y}{2},\dfrac{x - y}{2}) (x,y)(2x+y,2xy)。即旋转 π 4 \frac{\pi}{4} 4π 后缩小一半。

判断
  1. 点是否在直线上

( Q − P 1 ) × ( P 2 − P 1 ) = 0 (Q - P_1) \times (P_2 - P_1) = 0 (QP1)×(P2P1)=0
Q Q Q 在以 P 1 , P 2 P_1,P_2 P1,P2 为对角顶点的矩形内

  1. 两线段是否相交

① 快速排斥试验 若两矩形不相交,则线段不相交
② 跨立实验 ( P 1 − Q 1 ) × ( Q 2 − Q 1 ) ≥ 0 (P_1 - Q_1) \times (Q_2 - Q_1) \ge 0 (P1Q1)×(Q2Q1)0 和 $ (Q_2 - Q_1) \times (P_2 - Q_1) \ge 0$

  1. 线段和直线是否相交

只需用跨立实验判断即可。

  1. 点是否在多边形中

p p p 为端点,向左方作射线 L L L,根据交点个数的奇偶性判断。但需要注意与顶点相交、与边重合的特殊情况。

  1. 线段是否在多边形内

① 两线段端点在多边形内
② 线段与多边形所有边都不内交(两线段相交且交点不在两线段的端点)

做法是求出所有与线段相交的顶点,然后按照 ( x , y ) (x,y) (x,y) 排序,若相邻两点中点均在多边形内,则符合条件。

计算
  1. 点到线段的最近点

  2. 计算点到折线/矩形/多边形的最近点

  3. 计算点到圆的最近距离及交点坐标

  4. 求线段或直线与圆的交点

均可分为是否与坐标轴平行的两种情况。对于不平行的较复杂情况,通解为联立解方程组然后求出交点。

多边形
  1. 二维凸包

例题 P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包

① Andrew 算法 用单调栈维护,时间复杂度 O ( n log ⁡ n ) O(n \log n) O(nlogn)
② Graham 扫描算法 找到左下角的点,然后按极角排序。

  1. 旋转卡壳

例题 P1452 [USACO03FALL]Beauty Contest G /【模板】旋转卡壳

逆时针枚举凸包边,记录并维护一个当前的最近点(根据叉积计算三角形面积)

  1. 半平面交

例题 P4196 [CQOI2006]凸多边形 /【模板】半平面交

{ A 1 x + B 1 y + C 1 ≥ 0 A 2 x + B 2 y + C 2 ≥ 0 ⋯ A n x + B n y + C n ≥ 0 \begin{cases} A_1x + B_1y + C_1 \ge 0\\ A_2x + B_2y + C_2 \ge 0\\ \cdots\\ A_nx + B_ny + C_n \ge 0 \end{cases} A1x+B1y+C10A2x+B2y+C20Anx+Bny+Cn0

S & I S \& I S&I 算法 极角排序,然后维护单调队列(注意先判断队尾再判断队首的情况)

  1. 平面最近点对

例题 P7883 平面最近点对

分治的思想,以 P m P_m Pm 为界,拆分出点集 A 1 , A 2 A_1,A_2 A1,A2,然后分别找最近点对,距离为 h h h。再找一个点在 A 1 A_1 A1,另一个在 A 2 A_2 A2 的小于 h h h 的点对。最后的时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)

下午

有关链表的内容。

双向链表
  1. 插入
data[s] = x;
left[s] = left[p];
right[left[p]] = s;
right[s] = p;
left[p] = s;
  1. 删除
right[left[p]] = right[p];
left[right[p]] = left[p];
  1. 恢复
right[left[p]] = p;
left[right[p]] = p;
舞蹈链

P4929 【模板】舞蹈链(DLX)

一个运用链表到极致的例子。主要步骤如下:

① 矩阵 A A A 为空,返回已解决。

② 选择一列 c c c,通常选择 1 1 1 的个数最少的那一列。

③ a. 若 A r , c = 1 A_{r,c} = 1 Ar,c=1,说明行 r r r 存在,进入 ④;
b. 不存在,回溯,回溯删除,进入 ③ a.。

④ 把 r r r 包含进部分解。

⑤ 对于 ∀ j , A r , j = 1 \forall j,A_{r,j} = 1 j,Ar,j=1,若 ∀ i , A i , j = 1 \forall i,A_{i,j} = 1 i,Ai,j=1,删除第 i i i 行,否则删除第 j j j 行。

⑥ 重复递归。

舞蹈链的思想还可以运用到别的问题中去。我们将矩阵的行的意义为所有的情况,列的意义为约束条件。

  1. N N N 皇后问题

共有 n 2 n^2 n2 个格子,所以矩阵共有 n 2 n^2 n2 行。而因每行每列每斜行只能有一个皇后的约束条件,所以有 n n n n n n 列, 2 n − 1 2n - 1 2n1 条主对角线与副对角线,即矩阵共有 6 n − 2 6n - 2 6n2 列。

  1. 数独

先分析行,共有 9 × 9 9 \times 9 9×9 个格子,可以填入数字 1 1 1 9 9 9,所以共有 9 × 9 × 9 = 729 9 \times 9 \times 9 = 729 9×9×9=729 行。

每一个格子都需要填入数字,所以要有 9 × 9 9 \times 9 9×9 列存放是否已经填入数字的信息。接下去的 3 3 3 9 × 9 9 \times 9 9×9 列,分别记录行、列、宫的数字放置情况。所以共需要 4 × 81 = 324 4 \times 81 = 324 4×81=324 列。

跳表

例题 P3103 [USACO14FEB]Airplane Boarding G

跳表可以实现链表中的快速查找,从第一个位置的顶端开始一层层往下跳,直至返回 x x x 不存在。时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn),空间复杂度为 O ( n ) O(n) O(n)【建立在随机选择插入层的前提下】。

例题选讲

没听的太明白(其实跳表也不是很明白),选几道洛谷上有的题目列一下。

P7988 [USACO21DEC] HILO G

P1792 [国家集训队]种树

晚上

营员交流,属于是在听天书。几乎属于听不懂的状态,也就当长长见识了 qwq \texttt{qwq} qwq

今天一天累计算是听了 9 9 9 个多小时,休息去了! Day   2 \texttt{Day 2} Day 2 结束。


Day   3   2022.01.24 \texttt{Day 3 2022.01.24} Day 3 2022.01.24

上午

学习网络流,中午的时候到会议间中又听了听《多重时空下的算法竞赛》。

最大流

算法妙在建立反向边,主要步骤如下:

  • S → T S \to T ST 找到一条增广路

  • 求出流路径中边权最小的值

  • 维护路径中的反向边

  • 重复操作直到 S S S T T T 不再连通

于是问题就在于如何找增广路,于是有 SAP \textit{SAP} SAP 算法,即重建距离标号,将图分成若干个“层次”。其中包含的两个优化就是弧优化(如果一条边已经被增广过,那么它就没有可能被增广第二次)与断层优化(若图上出现了断层,也就是说无法再找到增广路,则可直接终止算法)。

那么这个算法快在哪里呢?通过探寻本质,只有减少冗余以及重复利用可以有效缩短时间。那么该算法通过距离标号,将原来相互独立的增广路相互联系,从而重复利用来节省时间。

费用流

下午

发现自己学过 tarjan 了,于是想就听听数据结构选讲。但一打开课件就发现都是什么 IOI \texttt{IOI} IOI 黑题,劝退了……还是听 tarjan 吧!

LCA \texttt{LCA} LCA

LCA   ( u , v ) = k \texttt{LCA }(u,v) = k LCA (u,v)=k,当遍历完 u u u 所在子树后, u u u 所在子树所有的结点跟 k k k 其它子树所有结点的 LCA \texttt{LCA} LCA 一定为 k k k。可以通过并查集维护。伪代码大概如下:

fa[v] = v;vis[v] = 1;
for (i...)
	if (!vis[i]) dfs (i),fa[i] = v;
for (v...)
	if (vis[u]) LCA[u][v] = LCA[v][u] = get_fa (u);

LCA   ( u , v ) = u \texttt{LCA }(u,v) = u LCA (u,v)=u,在结点 u u u 信息返回前, u u u 结点子树均已访问完,故伪代码此时仍然成立。

例题 codevs 1036 商务问题

题面中强调不存在环,故这是一棵树。考虑树上差分,则有 d i s i , j min ⁡ = d e p i + d e p j − 2 d e p L C A ( i , j ) dis_{i,j}{\min} = dep_i + dep_j - 2dep_{LCA(i,j)} disi,jmin=depi+depj2depLCA(i,j)

求割点

u u u 为生成树的根,则 u u u 为割点的充要条件是 u u u 的子树 ≥ 2 \ge 2 2

u u u 不为生成树的根,则 u u u 为割点的充要条件是在 v v v v v v 子孙结点和 u u u 祖先结点不存在回边。

可以使用时间戳来记录深度优先数与最低深度,有:

l o w [ u ] = min ⁡ { d f n [ u ] min ⁡ ( l o w [ v ] ∣ v   is   children ) min ⁡ ( d f n [ u ] ∣ ( u , v )   is   cross   edge ) low[u] = \min \begin{cases} dfn[u]\\ \min{(low[v]\mid v \texttt{ is children})}\\ \min{(dfn[u]\mid (u,v) \texttt{ is cross edge})} \end{cases} low[u]=min dfn[u]min(low[v]v is children)min(dfn[u](u,v) is cross edge)

u u u 存在一个孩子 v v v 使得 d f n [ u ] ≤ l o w [ v ] dfn[u] \le low[v] dfn[u]low[v],则 u u u 为割点。

割边

( u , v ) (u,v) (u,v) 为割边的充要条件是 u → v u \to v uv 不为重边且 v v v v v v 的子孙结点中没有指向 u u u u u u 祖先的回边。若 d f n [ u ] < l o w [ u ] dfn[u] < low[u] dfn[u]<low[u],则 ( u , v ) (u,v) (u,v) 为割边(与割点思想类似)。

辨析:

  • 两割点之间的边一定为割边。

错误!反例如下:

A-B     
| |  
C-D  
| |  
E F

C , D C,D C,D 为割点,但 ( C , D ) (C,D) (C,D) 不为割边。

  • 割边的两端点均为割点。

错误!反例如下:

A-B-C

( A , B ) (A,B) (A,B) 为割边,但 A A A 不为割点。

例题 P5058 [ZJOI2004]嗅探器

v v v 为割点 -> 子树中存在 b b b -> 所求之点

关键在于判断子树中是否存在 b b b,可以通过 d f n [ u ] dfn[u] dfn[u] 判定。若 d f n [ u ] < d f n [ b ] dfn[u] < dfn[b] dfn[u]<dfn[b],则符合条件。

例题 P7687 [CEOI2005] Critical Network Lines

课后补题,解析见我的博文 【题解】P7687 [CEOI2005] Critical Network Lines

强连通分量

注意,求割点与割边是在无向图中,而强连通分量是在有向图中,要注意区分。

l o w [ u ] < d f n [ u ] low[u] < dfn[u] low[u]<dfn[u],则子孙结点能连到自己上方的结点;若 d f n [ u ] = d f n [ u ] dfn[u] = dfn[u] dfn[u]=dfn[u],则 u u u 为根,内部仍存在一个或多个强连通分量,递归求解即可。

l o w [ u ] = d f n [ u ] low[u] = dfn[u] low[u]=dfn[u] 为结束条件进行弹栈得到强连通分量。

例题 P2341 [USACO03FALL][HAOI2006]受欢迎的牛 G

差不多可以说是板子题,缩点后判断是否只有 1 1 1 个出度为 0 0 0 的点。

晚上

趁着晚饭后做了课上讲的一道题,并写了篇题解。

还是营员交流,还是属于听不懂的状态。

Day   3 \texttt{Day 3} Day 3 结束。


Day   4   2022.01.25 \texttt{Day 4 2022.01.25} Day 4 2022.01.25

上午

数据结构中的复杂树问题,收获巨大!!!重点主要放在了前三个中,后面基本属于提了提。

树链剖分

轻重链剖分。一个定义就是重子结点表示其子结点中子树最大的子结点。

  1. 性质

① 在每条重链结点的 dfn 连续,即优先选择重子结点。
② 每个子树内的 dfn 连续。
③ 向下经过一条轻边,子树大小至少减半,不超过 log ⁡ n \log n logn 条重链。
④ 重链开头不一定为重子结点。

  1. 建树过程
void dfs1 (int u,int fa)
{
	sz[u] = 1;f[u] = fa;dep[u] = dep[fa] + 1;
	for (int i = head[u];i;i = nxt[i])
	{
		int v = to[i];
		if (v != fa)
		{
			dfs1 (v,u);
			sz[u] += sz[v];
			if (sz[v] > sz[hson[u]]) hson[u] = v;//求重儿子 
		}
	}
}
  1. 树的分解
void dfs2 (int u,int fa)
{
	if (hson[u])//优先走重边 
	{
		seg[hson[u]] = ++seg[0]; 
		top[hson[u]] = top[u];//重链的顶端
		rev[seg[0]] = hson[u];
		dfs2 (hson[u],u); 
	}
	for (int i = head[u];i;i = nxt[i])
	{
		int v = to[i];
		if (!top[v])
		{
			seg[v] = ++seg[0];
			rev[seg[0]] = v;
			top[v] = v;//此时 (u,v) 为轻边,v 为所在重链的顶端
			dfs2 (v,u); 
		}
	}
} 

P3384 【模板】轻重链剖分/树链剖分 模板题。

例题 P2590 [ZJOI2008]树的统计

通过向上跳来维护信息。若在重链上,则跳到顶端;若不在则在其顶端向上跳一步至重链。直到两点均在同一条重链上即可。核心代码如下:

void ask (int u,int v)
{
	int fx = top[u],fy = top[v];
	while (fx != fy)
	{
		if (dep[fx] < dep[fy]) swap (u,v),swap (fx,fy);//深度大的向上跳
		query (1,1,seg[0],seg[fx],seg[u]);
		u = f[fx],fx = top[u]; 
	}
	if (dep[u] > dep[v]) swap (u,v);
	query (1,1,seg[0],seg[u],seg[v]);//在同一条重链上的不同位置,最后需将这一段区间也进行求解 
}

再放一道练手的题目,几乎也是裸题。

P2146 [NOI2015] 软件包管理器

支持两种操作,树上的区间修改与子树的修改。注意因为涉及 0 0 0 1 1 1 两种情况,因此打懒标记的时候需要注意一下 if (tmp[cur] == -1) return ;,当然忽略这个语句就不存在这个问题了。

伸展树 splay \texttt{splay} splay

均摊时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn),通过势能分析可以得证。伸展树有一个性质,就是中序遍历不会改变。

  1. 右旋 zig(x)
    zig(x)

  2. 左旋 zag(x)

zag(x)

  1. rotate 函数

  2. splay 函数

  3. 插入

  4. 查找

  5. 分裂

  6. 合并

  7. 删除

  8. 找寻排名为 k k k 的数

  9. 区间删除

例题 P3391 【模板】文艺平衡树

例题 P3224 [HNOI2012]永无乡

例题 P2042 [NOI2005] 维护数列

下午

还是听《新版 NOI-Linux \texttt{NOI-Linux} NOI-Linux 系统使用》比较实用叭。

在电脑上成功装了一个 NOI-Linux \texttt{NOI-Linux} NOI-Linux 虚拟机,针不戳。捣鼓了一下午的虚拟机,效果如下:

1

2

非常好!~~~

Day   4 \texttt{Day 4} Day 4 结束。


Day   5   2022.01.26 \texttt{Day 5 2022.01.26} Day 5 2022.01.26

上午

IOI \texttt{IOI} IOI 命题方向。只是停留在听听的层面,但不得不说交互题和构造题等非传统题可以说是兴起了。还看到了一些“恶搞题”,印象最深的就是:

  1. 人工智能题?面向数据才是真理!

1

  1. MoMOOMoo

2

好像有个营员因“不文明语言”被管理员踢了…害怕 .jpg \texttt{.jpg} .jpg

下午

应该是冬令营的最后一节课了 awa \texttt{awa} awa,题目选讲,听听神仙是怎么爆切 IOI \texttt{IOI} IOI 的叭。

似乎今天 15 : 30 15:30 15:30 就结束了哈,明天结营测试, RP++ \texttt{RP++} RP++ 吧!

晚上

试机,没啥大问题。

Day   5 \texttt{Day 5} Day 5 结束。


Day   6   2022.01.27 \texttt{Day 6 2022.01.27} Day 6 2022.01.27

两道传统题,一道交互题。先开了 T2 \texttt{T2} T2,用空间换时间打了一个 O ( n m ) O(nm) O(nm)。然后发现啥都不会,交互题主要之前没有做过,所以就不太会格式,最后应该 CE \texttt{CE} CE 了。想着这样肯定也就不能拿牌,所以 T1 \texttt{T1} T1 25   pts \texttt{25 pts} 25 pts 最后也没拿。

Day   7   2022.01.28 \texttt{Day 7 2022.01.28} Day 7 2022.01.28 很后悔没打那个暴力,果然 Fe \texttt{Fe} Fe 了,被卡线 qwq \texttt{qwq} qwq

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值