Skip to content

Instantly share code, notes, and snippets.

@theoremoon
Last active March 31, 2020 06:08
Show Gist options
  • Select an option

  • Save theoremoon/f6ea97fb6125682d9d33c5cca030a509 to your computer and use it in GitHub Desktop.

Select an option

Save theoremoon/f6ea97fb6125682d9d33c5cca030a509 to your computer and use it in GitHub Desktop.
import std.stdio, std.string, std.algorithm, std.array, std.range, std.conv,
std.typecons, std.math, std.container, std.format, std.numeric;
struct SplayNode
{
public:
long value;
SplayNode* parent;
SplayNode* left, right;
long size;
/// rotate this node up on tree
void rotate()
{
SplayNode* pp, p, c;
p = this.parent;
pp = p.parent;
if (p.left == &this)
{
c = this.right;
this.right = p;
p.left = c;
}
else
{
c = this.left;
this.left = p;
p.right = c;
}
if (pp && pp.left == p)
{
pp.left = &this;
}
if (pp && pp.right == p)
{
pp.right = &this;
}
this.parent = pp;
p.parent = &this;
if (c)
{
c.parent = p;
}
p.update();
this.update();
}
int relation()
{
if (this.parent is null)
{
return 0;
}
if (this.parent.left == &this)
{
return 1;
}
if (this.parent.right == &this)
{
return -1;
}
return 0;
}
/// splay
void splay()
{
while (this.parent != null)
{
if (this.parent.relation == 0)
{
this.rotate();
}
else if (this.relation == this.parent.relation)
{
this.parent.rotate();
this.rotate();
}
else
{
this.rotate();
this.rotate();
}
}
}
void update()
{
this.size = 1 + this.lsize + this.rsize;
}
long lsize()
{
if (this.left is null)
{
return 0;
}
return this.left.size;
}
long rsize()
{
if (this.right is null)
{
return 0;
}
return this.right.size;
}
}
SplayNode* get(SplayNode* root, long i)
{
SplayNode* now = root;
while (true)
{
if (i < now.lsize)
{
now = now.left;
}
if (i == now.lsize)
{
now.splay();
return now;
}
if (i > now.lsize)
{
i = i - now.lsize - 1;
now = now.right;
}
}
}
void main(string[] args)
{
long p = 0;
long n;
readf("%d", &n);
const N = 200200;
SplayNode[] nodes = new SplayNode[](N);
foreach (i; 0 .. N - 1)
{
nodes[i].parent = &nodes[i + 1];
nodes[i + 1].left = &nodes[i];
nodes[i + 1].update();
}
SplayNode* root = &nodes[N - 1];
foreach (i; 0 .. n)
{
long ord, x;
readf("\n%d", &ord);
if (ord == 0)
{
// pushback
readf(" %d", &x);
root = root.get(p);
root.value = x;
root.update();
p++;
}
if (ord == 1)
{
// randomaccess
readf(" %d", &x);
root = root.get(x);
writeln(root.value);
}
if (ord == 2)
{
// popback
p--;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment