2023.10.11 闲话

_


完全可追溯化随机访问双端队列

维护一个双端队列的操作序列,支持以下修改 / 询问:

  1. \(\operatorname{Insert}(t,\operatorname{pushL}(x))\),在第 \(t\) 次操作后插入将元素 \(x\) 从左端加入双端队列操作 .
  2. \(\operatorname{Insert}(t,\operatorname{pushL}(x))\),在第 \(t\) 次操作后插入将元素 \(x\) 从右端加入双端队列操作 .
  3. \(\operatorname{Insert}(t,\operatorname{popL}())\),在第 \(t\) 次操作后插入弹出左端第一个数操作 .
  4. \(\operatorname{Insert}(t,\operatorname{popR}())\),在第 \(t\) 次操作后插入弹出右端第一个数操作 .
  5. \(\operatorname{Delete}(t)\),删除第 \(t\) 次操作 .
  6. \(\operatorname{Query}(t,i)\),询问 \(t\) 时刻后双端队列中 \(i\) 位置的值 .

考虑分别维护被 \(\operatorname{pushL}(x)\) 插入的元素和被 \(\operatorname{pushR}(x)\) 插入的元素 . 考虑双端队列的一种实现方式:维护序列 \(\{a\}\),初始 \(l=1,r=0\)

  • \(\operatorname{pushL}(x)\)\(l\gets l-1\)\(a_l=x\) .
  • \(\operatorname{pushR}(x)\)\(r\gets r+1\)\(a_r=x\) .
  • \(\operatorname{popL}()\)\(l\gets l+1\) .
  • \(\operatorname{popR}()\)\(r\gets r-1\) .

那么一次询问只需要知道 \(i\)\(a_i\) 就行了 . 维护两棵平衡树 \(T_{\rm L},T_{\rm R}\),对应平衡树只存对应的 \(\rm push,pop\) 操作,权值分别为 \(1,-1\) . 那么求 \(t\) 时刻的 \(i\) 值只需要在平衡树上求一下前缀和就可以了 .

\(a_i\) 的值肯定是最后一次 \(\operatorname{pushL}(x)\)\(l=i\) 的操作或者最后一次 \(\operatorname{pushR}(x)\)\(r=i\) 的操作,分别平衡树二分后比较即可 .

时间复杂度单次操作 \(O(\log m)\) .

\(\frak{ZG}\)

posted @ 2023-10-11 11:44  Jijidawang  阅读(26)  评论(1编辑  收藏  举报
😅​