Skip to content

Instantly share code, notes, and snippets.

@theoremoon
Created April 6, 2020 01:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theoremoon/66536c39c05a9d792cf8dd2f0ec55e2f to your computer and use it in GitHub Desktop.
Save theoremoon/66536c39c05a9d792cf8dd2f0ec55e2f 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:
SplayNode* parent, left, right;
long size;
long value, minimum;
void rotate()
{
SplayNode* p, pp, 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;
}
p.parent = &this;
this.parent = pp;
if (pp && pp.left == p)
{
pp.left = &this;
}
if (pp && pp.right == p)
{
pp.right = &this;
}
if (c)
{
c.parent = p;
}
p.update();
this.update();
}
auto relation()
{
if (this.parent is null)
{
return 0;
}
if (this.parent.left == &this)
{
return 1;
}
if (this.parent.right == &this)
{
return -1;
}
return 0;
}
void splay()
{
while (this.relation != 0)
{
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;
this.minimum = this.value;
if (this.left)
{
this.minimum = min(this.minimum, this.left.minimum);
}
if (this.right)
{
this.minimum = min(this.minimum, this.right.minimum);
}
}
long lsize()
{
return (this.left) ? this.left.size : 0;
}
long rsize()
{
return (this.right) ? this.right.size : 0;
}
}
/// get i-th element (0 indexed)
auto get(SplayNode* root, long i)
{
auto now = root;
while (true)
{
if (i < now.lsize)
{
now = now.left;
}
else if (i == now.lsize)
{
now.splay();
return now;
}
else if (i > now.lsize)
{
i = i - now.lsize - 1;
now = now.right;
}
}
}
/// split tree into left and right
/// left.size == left_cnt
auto split(SplayNode* root, long left_cnt)
{
if (left_cnt <= 0)
{
return tuple(cast(SplayNode*) null, root);
}
if (left_cnt >= root.size)
{
return tuple(root, cast(SplayNode*) null);
}
auto right = root.get(left_cnt);
auto left = right.left;
left.parent = null;
right.left = null;
right.update();
return tuple(left, right);
}
/// merge
auto merge(SplayNode* left, SplayNode* right)
{
if (left is null)
{
return right;
}
if (right is null)
{
return left;
}
left = left.get(left.size - 1);
left.right = right;
right.parent = left;
left.update();
return left;
}
/// insert node as i-th element
auto insert(SplayNode* root, long i, SplayNode* node)
{
auto tmp = root.split(i);
return merge(merge(tmp[0], node), tmp[1]);
}
/// remove i-th element
auto remove(SplayNode* root, long i)
{
root = root.get(i);
auto left = root.left;
auto right = root.right;
if (left)
{
left.parent = null;
}
if (right)
{
right.parent = null;
}
root.left = null;
root.right = null;
root.update();
return tuple(merge(left, right), root);
}
/// l and r are both inclusive
auto shift(SplayNode* root, long l, long r)
{
auto tmp = root.remove(r);
return tmp[0].insert(l, tmp[1]);
}
/// get minimum element in range [l, r]
auto query(SplayNode* root, long l, long r)
{
auto tmp = root.split(r + 1);
auto tmp2 = tmp[0].split(l);
auto ans = tmp2[1].minimum;
return tuple(merge(merge(tmp2[0], tmp2[1]), tmp[1]), ans);
}
void main(string[] args)
{
long n, q;
readf("%d %d\n", &n, &q);
auto node = new SplayNode[](n);
foreach (i; 0 .. n - 1)
{
node[i].parent = &node[i + 1];
node[i + 1].left = &node[i];
}
foreach (i; 0 .. n)
{
readf("%d\n", &(node[i].value));
node[i].update();
}
auto root = &node[$ - 1];
long x, y, z;
foreach (i; 0 .. q)
{
readf("%d %d %d\n", &x, &y, &z);
if (x == 0)
{
root = root.shift(y, z);
}
else if (x == 1)
{
auto tmp = root.query(y, z);
root = tmp[0];
writeln(tmp[1]);
}
else
{
root = root.get(y);
root.value = z;
root.update();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment