深入浅出程序设计竞赛(进阶篇)进阶数据结构

第五章 二叉堆

P2168 [NOI2015] 荷马史诗

哈夫曼树

P2827 [NOIP2016 提高组] 蚯蚓

找最长的蚯蚓只需要直到相对大小,其余蚯蚓长度 \(+q\) 等价于新产生的两条蚯蚓长度 \(-q\)

新产生的第一/二条蚯蚓长度分别单调,可以用队列代替堆

时间复杂度 \(O(n\log n+m)\)

P1801 黑匣子

对顶堆

P1631 序列合并

\(a,b\) 不降所以 \(a[i]+b[j]\) 一定比 \(a[i+1]+b[j],a[i]+b[j+1]\)

用堆维护可能成为答案的数对,取出 \((i,j)\) 后放入 \((i+1,j),(i,j+1)\)

P4053 [JSOI2007] 建筑抢修

反悔贪心

第六章 线段树

P1438 无聊的数列

区间加等差数列

懒标记记录(首项,公差),下传时可以根据左子区间长度算出右子区间的首项,合并时首项、公差对应相加即可

P3373 【模板】线段树 2

有乘、加两个标记,记作 \((k,b)\)。比较自然的想法是让值为 \(ka+b\)\(\times x\)\((ka+b)x=kxa+bx\)\(+x\)\((ka+b)+x=ka+(b+x)\),仍然可以用 \((k,b)\) 表示

\(ka+b\) 经过 \((k',b')\) 作用时需要考虑下传顺序。注意到下传乘标记时加标记也乘了,所以应该先乘后加得到 \((ka+b)k'+b'\)

P4513 小白逛公园

区间最大子段和

维护区间最大子段和、最大前缀和、最大后缀和、区间和

P4145 上帝造题的七分钟 2 / 花神游历各国

\(10^{12}\) 开方下取整 \(6\) 次就变成 \(1\) 了,之后的开方都没有意义

其实不需要线段树,并查集 + BIT 即可

第七章 树状数组与字典树

lowbit(x) = x&-x\(-x\) 的补码是 \(x\) 按位取反再 \(+1\),那么 \(x\) 末尾连续的 \(0\) 取反 \(+1\) 后恰好进位到 lowbit(x)

如果结点 \(j\) 包含位置 \(i\) 的信息,那么:

  • \(j\ge i\)
  • \(\text{lowbit}(j)\ge\text{lowbit}(i)\)\(j=i\) 时取等):考虑 \([j-\text{lowbit}(j)+1,j]\) 中的所有数
  • 这些 \(j\) 的 lowbit 互不相等:lowbit 相等的结点覆盖的区间无交

P5283 [十二省联考 2019] 异或粽子

\(n\) 个数。给定 \(i\),求 \(a[i]\oplus a[j]\) 的第 \(k\) 大值

trie 上维护每个子树的数字数量,查询类似线段树二分

P2161 [SHOI2009] 会场预约

sol

P3586 [POI2015] LOG

先让 \(c\) 减掉 \(\ge s\)\(a[i]\) 个数,之后只考虑 \(<s\)\(a[i]\)

结论:只要 \(\sum a[i]\ge cs\) 就可行
证明:考虑构造 \(s\)\(c\) 列的表格,每行的 \(c\) 个数表示要 \(-1\) 的下标,从上到下、从左到右填表即可。\(\sum a[i]\ge cs\) 保证了能填满,\(a[i]<s\) 保证了一行不会有两个相同数

P4592 [TJOI2018] 异或

DFS 序上的可持久化 01trie 实现子树询问
根链上的可持久化 01trie 配合树上差分实现链询问

第八章 线段树的进阶用法

P4587 [FJOI2016] 神秘数

对于给定可重集,从小到大依次考虑数 \(x\):设 \(r\) 是当前最小的不能被表示的数,若 \(x\le r\),那么 \(r\leftarrow r+x\),否则答案就是 \(r\)
据此得出做法:设 \(r'\) 为上次最小的不能被表示的数,\((r',r]\) 中的数都可以累加进 \(r\) 中,没有数可以累加则结束。每次累加的数 \(>r'\),最多累加 \(\log a\)

P3293 [SCOI2016] 美味

\(\max_{i=l}^{r}\{b\oplus a[i]+x\}\)

仍然是从高到低逐位贪心。设 \(b\) 的第 \(i\) 位为 \(1\),当前确定的答案为 \(b\oplus c\),若 \([c-x,c-x+2^{i}-1]\) 中有数那么不操作,否则令 \(c\leftarrow c+2^{i}\)

时间复杂度 \(O(m\log a\log n)\)

CF960F Pathwalks

有向图上边的 LIS

P2617 Dynamic Rankings

动态区间第 \(k\)

P2839 [国家集训队] middle

\(<mid\) 的数看作 \(-1\)\(\ge mid\) 的看作 \(1\),区间和 \(\ge0\) 代表中位数 \(\ge mid\)。可以通过对值域建主席树实现

二分答案 \(mid\)。求 \([a,b]\) 最大后缀和 \(+(b,c)\) 区间和 \(+[c,d]\) 最大前缀和即可判断

P5445 [APIO2019] 路灯

sol

posted @ 2023-09-21 20:27  ft61  阅读(897)  评论(1)    收藏  举报