18:56:13
icon

ここによくいるユーザーの誰かの投稿がXで伸びているのを発見(相互確証破壊)

20:24:30
icon

1/2

:: Treap {
  @init() {
    return {len: 0, end: {v: null, id: 1, l: null, r: null, p: null}}
  }
  @empty(a) {return a.len == 0}
  @size(a) {return a.len}
  @begin(a) {
    var res = a.end
    loop {
      if res.l == null break
      res = res.l
    }
    return res
  }
  @end(a) {return a.end}
  @rotateLeft(n) {
    var par = n.p
    if par.p.r == par {par.p.r = n}
    else {par.p.l = n}
    n.p = par.p
    par.r = n.l
    if n.l != null n.l.p = par
    par.p = n
    n.l = par
    return null
  }
  @rotateRight(n) {
    var par = n.p
    if par.p.r == par {par.p.r = n}
    else {par.p.l = n}
    n.p = par.p
    par.l = n.r
    if n.r != null n.r.p = par
    par.p = n
    n.r = par
    return null
  }
  @insert(a,v) {
    if a.len == 0 {
      a.len += 1
      let val = {v: v, id: Math:rnd(), l: null, r: null, p: a.end}
      a.end.l = val
      return val
    }
    var tmp = a.end.l
    var insertRight = false
    loop {
      if tmp.v == v return tmp
      if v < tmp.v {
        if tmp.l == null {
          insertRight = false
          break
        }
        tmp = tmp.l
      }
      else {
        if tmp.r == null {
          insertRight = true
          break
        }
        tmp = tmp.r
      }
    }
    a.len += 1
    let id = Math:rnd()
    var val = {v: v, id: id, l: null, r: null, p: tmp}
    if insertRight {
      tmp.r = val
    }
    else {
      tmp.l = val
    }
    loop {
      if val.id < val.p.id break
      if val.p.r == val {rotateLeft(val)}
      else {rotateRight(val)}
    }
    return val
  }
  @erase(a,v) {
    if a.len == 0 return false
    var val = a.end.l
    loop {
      if v == val.v break
      if v < val.v {
        if val.l == null return false
        val = val.l
      }
      else {
        if val.r == null return false
        val = val.r
      }
    }
    a.len -= 1
    val.id = -1
    loop {
      if val.l == null {
        if val.r == null break
        else rotateLeft(val.r)
      }
      else {
        if val.r == null rotateRight(val.l)
        else {
          if val.l.id < val.r.id rotateLeft(val.r)
          else rotateRight(val.l)
        }
      }
    }
    if val.p.r == val val.p.r = null
    else val.p.l = null
    return true
  }
}

20:25:53
icon

2/2

:: Treap {
  @find(a,v) {
    if a.len == 0 return a.end
    var val = a.end.l
    loop {
      if v == val.v break
      if v < val.v {
        if val.l == null return a.end
        val = val.l
      }
      else {
        if val.r == null return a.end
        val = val.r
      }
    }
    return val
  }
  @lowerBound(a,v) {
    var res = a.end
    if a.len == 0 return res
    var val = a.end.l
    loop {
      if val.v < v {
        if val.r == null break
        val = val.r
      }
      else {
        res = val
        if val.l == null break
        val = val.l
      }
    }
    return res
  }
  @upperBound(a,v) {
    var res = a.end
    if a.len == 0 return res
    var val = a.end.l
    loop {
      if v < val.v {
        res = val
        if val.l == null break
        val = val.l
      }
      else {
        if val.r == null break
        val = val.r
      }
    }
    return res
  }
  @next(n) {
    if n.r == null {
      var res = n
      loop {
        if res.p.l == res break
        res = res.p
      }
      return res.p
    }
    else {
      var res = n.r
      loop {
        if res.l == null break
        res = res.l
      }
      return res
    }
  }
  @prev(n) {
    if n.l == null {
      var res = n
      loop {
        if res.p.r == res break
        res = res.p
      }
      return res.p
    }
    else {
      var res = n.l
      loop {
        if res.r == null break
        res = res.r
      }
      return res
    }
  }
}

20:28:23
icon

使用例

var a = Treap:init()
Treap:insert(a,3)
Treap:insert(a,1)
Treap:insert(a,4)
Treap:insert(a,1)
Treap:insert(a,5)
Treap:insert(a,9)
<:Treap:size(a)
<:"---"
var i = Treap:begin(a)
loop {
  <:i.v
  i = Treap:next(i)
  if i == Treap:end(a) break
}
<:"---"
Treap:erase(a,3)
Treap:erase(a,1)
Treap:erase(a,2)
Treap:erase(a,5)
<:Treap:size(a)
<:"---"
i = Treap:end(a)
loop {
  i = Treap:prev(i)
  <:i.v
  if i == Treap:begin(a) break
}
// 5
// 1 3 4 5 9
// 2
// 9 4