妙妙屋
如何快速求出一个点 \(u\) 到一堆点的最短路的最短值?
新建一个虚点 \(v\) ,向这堆点中的每一个都连一条0权边,然后跑 \(u,v\) 之间的最短路。
如何在多组询问下,快速求出字符串 \(s,t\) 的 \(min\{\)最长公共前缀长度,最长公共后缀长度\(\}\)?
\(\forall 1 \le i \le |s|\) ,将字符对 \((s_i,s_{|s|-i+1})\) 视为一个新的字符记录为新字符串 \(s'\) 的第 \(i\) 个字符,对 \(t\) 也如此处理。
那么原式即 \(s',t'\) 的最长公共前缀的长度,用 \(trie\) 处理。
状态压缩时如何枚举子集?
设 \(i\) 为当前状态,\(j\) 为子状态。
先奉上代码:
for(int j=i;j=(j-1)&i;) ...
为什么这么做是对的:每次 j=j-1 的时候都会把 j 的末位 1 变成 0 ,而把末位 1 之后的 0 都变成 1 。然后再进行 j&=i ,相当于是在只关注 i 中的 1 时进行了一次退位减法的操作。
冒泡排序的性质:
对一个序列进行单次冒泡排序(不妨假设为从小到大排序)后,考虑任意一个区间 \([l,r]\),至多有一个数会进入这个区间,也至多有一个数会进入这个区间。
特别地,从集合的视角考虑前缀 \([1,r]\),在冒泡排序 \(k\) 轮之后,前缀内的数恰好由原序列 \([1,min(r+k,n)]\) 内前 \(r\) 小的数组成。
当集合内每一个元素都具有 \(\le 2\) 个属性时,可以建图,将属性视为图中的点,将元素视为图中连接两个属性的边。
例如,给定若干长度 \(1\) 或 \(2\) 的字符串,每个串可以翻转,求能否恰好使用所有串,拼接成一个回文串。
可以建图,将每种字符视为一个点,每个串视为连接其两个字符的无向边。特别地,对于长度 \(=1\) 的串,新建 \(0\) 号点,视为 \(0\) 号点与这个串的唯一字符之间连边。
则图上的一条欧拉回路对应一个回文串,转换得很巧妙。
树上询问某一个点所在连通块,可以考虑将这个问题分为以下多个部分。
1.将连通块挂到其根处。
2.询问一个点所在连通块的根。
3.在根上维护连通块信息。
树剖后,任意的链上修改通过树上差分转换为根到某一点的链上修改。
dp时,为了计算方便,可以引入不优解。
对于 \(01\) 序列或者 \(\pm 1\) 序列,可将其视为折线,考虑其几何意义、值域连续性质等。
当数据范围中某个量极小,考虑分类讨论、状态压缩,容斥等。
问题与值域规模相关时,可以考虑值域 \(=[0,1]\) 的简化情况,并用二分、离散化等手段解决原问题。
同理,树上问题可以考虑菊花、链等简化情况,进而利用分析、树剖等手段推广。
同理,对于 dp、数据结构等问题,可以先想暴力,再想优化。
由易到难是很重要的思考角度。
绝对值的处理方法(待补全):
- 直接拆开。
比如 \(|a+b|\le c+d\),可以将其化为 \(-c-d \le a+b \le c+d\),下一步可以考虑对这个不等式移项,合并同一下标的各个属性方便计算等。下面是一道简要例题。
现有长度为 \(n(n \le 5 \times 10^5)\) 的二元组序列 \((a_i,b_i)(1\le i \le n)\)。请构造一个尽可能长的正整数序列 \(id\),\(id\) 需要满足 \(\forall 1\le i < |id|,~|a_{id_{i+1}}-a_{id_i}|\le b_{id_{i+1}}-b_{id_i}\)。
将绝对值拆开,得到
移项,得
记 \(x_i=a_i+b_i~,y_i=b_i-a_i\),得
将二元组序列 \((x_i,y_i)\) 按 \(x\) 升序排序,其余的就是一个在 \(y\) 上的 LIS 问题。
怎么 HBCPC 热身赛的最后一题也是这个套路……
又例如需要计算二维曼哈顿距离最大值,可以将 \(\max\{|x-x_i|+|y-y_i|\}\) 拆分成四个式子,进而只需维护 \(x_i \pm y_i\) 的最大值和最小值。
例题见 P12463。
可以发现拆开绝对值,使得同一下标的各个属性合并,简化了维护过程。
-
排序,最小化绝对值之和。
-
将绝对值拆分成若干段,对每一段的贡献分别求解。例题见 CF1427G。
利用程序的随机打乱等手段可以破坏交互题的构造数据,实现数据随机化。
对于非常规的背包问题,有以下思考角度:
-
优先贪心,考虑性价比。例题1 例题2(H. Jewel Thief)
-
进行神秘复杂度分析。例题
-
用 bitset 碾。
-
同余最短路。例题
-
多项式此知识点不在 NOI 大纲内。
集合计数/维护信息类问题,考虑对每个集合取一个代表元,之后维护代表元。
例如树上查询连通块时,取代表元为连通块的根,从而维护根处信息。
需要注意,代表元应与集合存在双射关系。
缩树之后得到的新树,其本质是在原树上选一些连通块,并且仅保留连通块之间的边所得到的树。连通块内的边对应着缩的边,新树形态与缩边顺序无关。
缩树,指在一棵树中选定一条边 \((u,v)\),对于所有 \(v\) 的非 \(u\) 的邻居 \(x\),删除边 \((v,x)\),添加边 \((u,x)\)。
(打破一下严肃的气氛)
萌新刚学 OI,zkw 线段树的区间查询思路真的太高妙了!
查询 \([l,r]\) 时,新建两个指针 \(l-1,~r+1\),让这两个家伙往父亲上跳,跳的过程中如果遇到位于查询区间内的兄弟,就把兄弟算一次贡献。
这个东西结合位运算有很多优秀的性质!
折线上 DP 的一个特征:可以把所有点分为两类,且存在某个二维偏序关系一定不优。此时存在一条折线,将折线两侧的点分为两类最优。
可以结合扫描线等方法优化。

浙公网安备 33010602011771号