2022.10.2 闲话

线段树维护信息的一些描述方法 .

也就是所谓的「直接线段树」,不加转换,直接暴力维护 .

我见的题比较少所以就不多放了 .

搞笑图:

置换

其实置换和矩阵本质上是等价的,置换就可以看作是向量 .

CF911G Mass Change Queries

给一个序列 \(\{a_n\}\)\(q\) 次操作,每次给四个整数 \(l,r,x,y\),表示将区间 \([l,r]\) 中等于 \(x\) 的数改成 \(y\) . 输出 \(q\) 步操作完的数列 .

\(1\le n,q\le 2\times 10^5\),任意时刻序列中最大值不大于 \(100\),不小于 \(1\) .

未来日记

对每个点维护一个置换(实际上也不太算置换,因为是可重的,大概就是维护序列 \(\{p\}\) 表示原来的 \(x\) 经过一波操作之后变成了 \(p_x\)),然后这个操作就是区间复合上一个置换 .

线段树维护即可,时间复杂度 \(O(qL\log n)\)\(L\) 是值域 .

要稍微精细实现一下 .

线段树 7

有一个骰子,四个操作 UDLR,表示向某个方向滚一下 .

维护一个操作序列,\(q\) 次操作,支持:

  • change x y,将第 \(x\) 个操作改成 \(y\) .
  • query l r,询问初始的骰子按顺序经过 \([l,r]\) 的所有操作后最上面的面是什么 .

\(1\le n,q\le 2\times 10^5\) .

可以用一个二元组表示横轴和纵轴的贡献,这样就可以朴素合并了,问题也就解决了 .

一个看起来比较巧妙的方法是用复数表示状态 .

时间复杂度 \(O(q\log n)\) .

也可以说是维护了一个置换吧 .

SHOI2010 滚动的正四面体

一个正四面体,有三个方向 LRB 可以滚,每次滚就是一次操作 .

初始正四面体的 X 面朝向地面 .

维护一个操作序列,\(q\) 次操作,支持:

  • change x y,将第 \(x\) 个操作改成 \(y\) .
  • query l r,询问初始的正四面体按顺序经过 \([l,r]\) 的所有操作后 X 面有多少时刻朝向地面 .

\(1\le n\le 6\times 10^4\)\(1\le q\le 1.5\times 10^5\) .

和线段树 7 是一样的,维护一下 \(f(l,r)\) 表示初始的正四面体按顺序经过 \([l,r]\) 的所有操作后哪面朝下,然后再维护 \(s(l,r)\) 表示初始的正四面体按顺序经过 \([l,r]\) 的所有操作后 X 面有多少时刻朝向地面即可 .

时间复杂度 \(O(q\log n)\) .

矩阵 / DDP

如果转移是常系数齐次线性递推,那么就可以矩阵快速幂优化 .

不齐次其实也行,不过比较麻烦 .

高端题可以看 Miracle 的博客 .

CF1252K Addition Robot

给出一个长度为 \(n\),只含有大写字母 \(\tt A\)\(\tt B\) 的字符串 \(S=S_1S_2S_3...S_n\),定义如下函数 \(f(L,R,A,B)\)

function f(L, R, A, B):
	FOR i from L to R
		if S[i] = 'A'
			A = A + B
		else
			B = A + B
	return (A, B)

给出初始字符串 \(S\)\(q\) 次操作:

  • 1 L R:将 \(S_L,S_{L+1},...,S_{R-1},S_r\) 取反(A 变为 B,B 变为 A) .
  • 2 L R A B:输出函数调用 \(f(L,R,A,B)\) 的结果,对 \(10^9+7\) 取模 .

\(1\le n,q\le 10^5\) .

这种板子大水题不用多说吧 /hsh

\(A=A+B\)\(B=A+B\) 可以用矩阵来描述:\(A,B\) 翻转可以直接交换矩阵中的元素 .

然后就没啥了吧,时间复杂度 \(\Theta(q\log n)\) .

Luogu P7706 文文的摄影布置

题面 .

维护 \(A,B\) 的区间 max,区间内 \(|A_i-B_j|\) 其中 \(i\ne j\) 的 min 即可 .

思路和 GSS1 / GSS3 差不多 .

时间复杂度 \(\Theta(q\log n)\) .

Segment Tree Beats!

题面 .

用广义矩阵维护一下就好了,具体不想说了,看 wangrx 的题解 .

时间复杂度 \(O(q\log^2 n)\) .

多项式

CF407C Curious Array

Luogu P1438 无聊的数列

General (Static)

给一个序列 \(\{a_n\}\),有一个固定的 \(k\) 次多项式 \(f(z)\) .

\(q\) 次操作,每次给两个整数 \(l,r\),表示对于每个 \(l\le i\le r\),让 \(a_i\gets a_i+f(i-l+1)\) .

所有操作结束后,输出最后的序列 \(\{a\}\) .

如果值域比较小可以维护置换,类似 CF911G .

否则就 \(k\) 次差分,然后朴素线段树维护,最后 \(k\) 次前缀和回来 .

时间复杂度 \(O(qk^{o(1)}\log n)\) .

一般也就是用 \(k\) 比较小的情形,所以这边就不分析到最细了 .

General (Dynamic)

维护一个序列 \(\{a_n\}\),有一个固定的 \(k\) 次多项式 \(f(z)\) .

\(q\) 次操作:

  • change l r,表示对于每个 \(l\le i\le r\),让 \(a_i\gets a_i+f(i-l+1)\) .
  • query l r,求 \(\displaystyle\sum_{i=l}^ra_i\),也就是区间和 .

感觉不太能做,大概就是维护多项式系数吧 .

时间复杂度 \(O(qk^{o(1)}\log n)\) .

posted @ 2022-10-02 20:32  Jijidawang  阅读(75)  评论(6编辑  收藏  举报
😅​