Ynoi2007 rfplca(分块,均摊分析)

  • 题目链接:Ynoi2007 rfplca
  • 题意简述:给你一个以\(1\)为根的\(n\)个点的树,点\(i\)的父亲为\(fa_i\)
  • 要求支持以下\(q\)个操作
  • 1 l r x \(\forall i \in [l,r],fa[i]:= max(fa[i]-x,1)\)
  • 2 u v,询问\(lca(u,v)\)
  • \(n,q \leq 4e5\),强制在线
  • solution

  • 以后再也不敢做\(Ynoi\)了,大常数选手不配
  • 考虑分块,我们设\(par(u)\)表示\(u\)的父亲,\(Fa(u)\)表示第一个跳出块的祖先,那么询问可以通过以上两个信息\(O(\sqrt n)\)求出
  • 考虑如何维护,我们发现若\(par(u) = Fa(u)\),我们可以直接对其打标记.否则我们对每个块维护一个队列,按\(par(u)\)排序,表示\(par(u) != Fa(u)\)的点的集合,每次暴力修改,若修改之后\(par(u) == Fa(u)\),则将其弹出,容易发现在排序后\(-x\),弹出一定是从队首弹出
  • 为什么暴力修改是对的呢\(?\),考虑均摊分析,每次修改使得\(par_u\)至少减\(1\),而想要让\(par(u) == Fa(u)\),最多只要让\(par_u -= \sqrt n\),所以均摊下来是\(O(n \sqrt{n})\)
  • 散块暴力重构,暴力排序维护队列即可,时间复杂度\(O(n \sqrt n \log n)\)
  • 这么假的复杂度还想过\(Ynoi\)?

  • 我们注意到队列其实完全不需要,我们对每个块另外标记一个\(cnt_{u}\),表示其被整块修改了几次,\(if(cnt_{u} \leq \sqrt n)\),就暴力修改,否则维护,容易发现,这样均摊下来复杂度还是\(O(n\sqrt n)\),而没有了排序,总复杂度就是\(O(n \sqrt n)\)
  • 代码先咕咕,\(sb\)博主常数巨大还算错复杂度
  • \(Tag:分块,均摊分析\)
posted @ 2021-03-31 17:05  y_dove  阅读(116)  评论(0编辑  收藏  举报