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)\) .
以下是博客签名,正文无关
本文来自博客园,作者:Jijidawang,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/16749400.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ