当前位置: 首页 > news >正文

一种“用平衡树修改自己”的算法

最近在考试时发现可以用 \(FHQ-Treap\ O(n\log^2n)\) 做一些事情,觉得很有趣,就记录下来。若有与他人重复,还请提醒。


起因是考场上遇到了这样一个问题:

有两个数列 \(a,c\),满足 \(c_i<i\)。从前往后对于每个位置,求出一个数对 \(p_i=(a_i,d_i)\),其中 \(d_i\in [c_i,i)\),要求 \(d_i\)\([c_i,i)\)\(p_i\) 最小的位置。对于两个数对排序方式是:先比较 \(a_i,a_j\) 的大小,若相同比较 \(p_{d_i}\)\(p_{d_j}\) 的大小。要求时间复杂度为 \(O(n\log^2n)\)

容易发现,假如我们在求解 \(p_i\) 的时候,已经知道了前 \(i-1\) 个位置的 \(p\) 数组排名,那么我们可以用线段树简单维护每个 \(d_i\)。难点在于如何排序。

容易发现当你塞入一个新的数对 \(p_i\) 时,比 \(p_i\) 大的数对排名会 \(+1\)。因此考虑可以进行区间加的 \(FHQ-Treap\)。但是难点在于如何利用平衡树自身的排名进行分裂。因为假如我们只按照每个位置上记录的排名进行排序,可能会出现懒标记暂未下放的情况;而分裂操作会破坏树结构,因此普通平衡树中的查排名操作也无法实施。

考虑不下放标记,而让节点通过向上一步一步爬的方式找标记。定义 getnum(x) 函数表示我们从 \(x\) 开始,一直执行向父亲跳和给 \(x\)\(num\) 加上当前点的懒标记值的操作,最终得出的数就是这个位置的真实排名,代码如下:

inline int getnum(int x){int re=num(x);x=fa(x);while(x) re+=fl(x),x=fa(x);return re;
}

由于平衡树深度为 \(O(\log n)\),所以这一操作的时间复杂度即为 \(O(\log n)\)。由于 \(split\) 操作本身就有一个 \(\log\),所以现在 \(split\) 的总时间复杂度为 \(O(\log^2n)\)。代码如下:

inline int getnum(int x){int re=num(x);x=fa(x);while(x) re+=fl(x),x=fa(x);return re;
}
inline bool operator<(suf x,suf y){return x.fs!=y.fs?x.fs<y.fs:getnum(x.ls)<getnum(y.ls);
}
inline void push_up(int x){sz(x)=sz(ls(x))+sz(rs(x))+1;
}
inline void down(int x,int k){fl(x)+=k,num(x)+=k;
}
inline void push_down(int x){down(ls(x),fl(x)),down(rs(x),fl(x)),fl(x)=0;
}
inline void split(int x,suf v,int &a,int &b,int af,int bf){if(!x){a=b=0;return;}push_down(x);if(v<val(x)) split(ls(x),v,a,ls(b=x),af,x),fa(x)=bf;else split(rs(x),v,rs(a=x),b,x,bf),fa(x)=af;push_up(x);
}
inline int merge(int x,int y){if(!x||!y) return x|y;push_down(x),push_down(y);if(rk(x)<rk(y)) return rs(x)=merge(rs(x),y),fa(rs(x))=x,push_up(x),x;return ls(y)=merge(x,ls(y)),fa(ls(y))=y,push_up(y),y;
}

这样我们就可以用总时间复杂度 \(O(n\log^2n)\) 的做法 \(AC\) 这个问题了。由于时间复杂度非均摊,所以理论上可以做可持久化。另外,本题理论上可以将区间加改为区间反转等更复杂的区间操作。

http://www.zskr.cn/news/55856.html

相关文章:

  • format函数sql的指南
  • format函数sql的技巧
  • 详细介绍:Flink 的 checkpoint 对 key state 是怎么样存储的?
  • 2025年质量好的深睡记忆棉枕厂家最新TOP实力排行
  • format函数sql的实例
  • format函数sql的作用
  • 不完全的质因数分解?
  • 2025年评价高的防尘灌溉管件厂家最新TOP实力排行
  • 2025年热门的医疗污水处理设备厂家最新推荐权威榜
  • 2025年靠谱的胶辊硅橡胶TOP实力厂家推荐榜
  • 2025年口碑好的年轻人喜爱轻时尚家居美学品牌人气榜
  • 2025年比较好的干法选煤设备用户好评厂家排行
  • 2025年比较好的GEO公司行业领先榜
  • formac环境下mysql性能调优技巧
  • formac上mysql故障排查方法
  • 读社会工程:安全体系中的人性漏洞(第2版)07读后总结与感想兼导读
  • for linux是什么意思
  • AI元人文:内观照、欲望值与自感性的情感星辰
  • for linux
  • 2025 年 11 月战略/供应链管理咨询公司权威推荐榜:专业规划与高效执行助力企业优化运营与成本控制
  • 2025 年 11 月精益生产管理咨询公司推荐排行榜,精益生产管理咨询服务机构,工厂精益化管理咨询公司,生产管理咨询公司哪家强,精细化管理咨询公司选哪家
  • 2025 年 11 月管理咨询公司推荐排行榜,企业管理咨询,制造业工厂咨询,驻场运营管理咨询,企业转型升级服务机构推荐
  • 2025 年 11 月手工冰淇淋厂家推荐排行榜,0添加冰淇淋,低脂冰淇淋,低糖冰淇淋,巧克力冰淇淋,国潮冰淇淋,磨巧冰淇淋公司精选
  • 2025 年 11 月战略/供应链管理咨询公司权威推荐榜单:供应链管理咨询机构,战略管理咨询服务机构,企业战略管理咨询公司,供应链顾问公司精选排行
  • 2025 年 11 月精密行星减速机厂家推荐排行榜,精密行星/微型精密行星/重载精密行星/人形精密行星/关节精密行星减速机/减速器公司精选
  • 2025 年 11 月塑胶容器厂家推荐排行榜,塑料容器,透明塑胶容器,吹塑容器,容器瓶,医药容器公司精选
  • first sql有啥要点
  • AI元人文:论“静默运维”与“悟空时刻”——阈值触发的人机共舞
  • find -name linux
  • fdisk在Linux中怎样分配磁盘空间