Templates of basic data structures
Binary Indexed Tree
class BinaryIndexedTree
{
private int[] array = null;
private int capacity = 0;
public BinaryIndexedTree(int capacity)
{
array = new int[capacity];
this.capacity = capacity;
}
private int Lowbit(int num)
{
return num & (-num);
}
public void Plus(int pos, int num)
{
while (pos <= this.capacity)
{
array[pos] += num;
pos += Lowbit(pos);
}
}
public int Sum(int end)
{
int sum = 0;
while (end > 0)
{
sum += array[end];
end -= Lowbit(end);
}
return sum;
}
}
Segment tree
class SegmentTree
{
private SegsegmentTreeNode[] segmentTree = null;
private int[] originalArray = null;
public SegmentTree(int[] array)
{
segmentTree = new SegsegmentTreeNode[4 * array.Length];
originalArray = array;
SegT_Build(0, array.Length - 1, 1);
}
struct SegsegmentTreeNode
{
public int Left, Right;
public long add, Sum;
public long Min, Max;
}
private int SegT_L(int x)
{
return x << 1;
}
private int SegT_R(int x)
{
return x << 1 | 1;
}
private int SegT_SZ(int x)
{
return segmentTree[x].Right - segmentTree[x].Left + 1;
}
private void SegT_Update(int p)
{
segmentTree[p].Sum = segmentTree[SegT_L(p)].Sum + segmentTree[SegT_R(p)].Sum;
segmentTree[p].Max = Math.Max(segmentTree[SegT_L(p)].Max, segmentTree[SegT_R(p)].Max);
segmentTree[p].Min = Math.Min(segmentTree[SegT_L(p)].Min, segmentTree[SegT_R(p)].Min);
return;
}
private void SegT_Spread(int p)
{
if (segmentTree[p].add == 0) return;
segmentTree[SegT_L(p)].Max += segmentTree[p].add;
segmentTree[SegT_R(p)].Max += segmentTree[p].add;
segmentTree[SegT_L(p)].Min += segmentTree[p].add;
segmentTree[SegT_R(p)].Min += segmentTree[p].add;
segmentTree[SegT_L(p)].add += segmentTree[p].add;
segmentTree[SegT_R(p)].add += segmentTree[p].add;
segmentTree[SegT_L(p)].Sum += segmentTree[p].add * SegT_SZ(SegT_L(p));
segmentTree[SegT_R(p)].Sum += segmentTree[p].add * SegT_SZ(SegT_R(p));
segmentTree[p].add = 0;
SegT_Update(p);
return;
}
private void SegT_Build(int l, int r, int p)
{
segmentTree[p].Left = l;
segmentTree[p].Right = r;
if (l == r)
{
segmentTree[p].Min = segmentTree[p].Max = segmentTree[p].Sum = originalArray[l];
return;
}
int mid = segmentTree[p].Left + (segmentTree[p].Right - segmentTree[p].Left) / 2;
SegT_Build(l, mid, SegT_L(p));
SegT_Build(mid + 1, r, SegT_R(p));
SegT_Update(p);
return;
}
private void SegT_Change(int l, int r, int p, long v)
{
if (l <= segmentTree[p].Left && segmentTree[p].Right <= r)
{
segmentTree[p].add += v;
segmentTree[p].Min += v;
segmentTree[p].Max += v;
segmentTree[p].Sum += v * SegT_SZ(p);
return;
}
SegT_Spread(p);
int mid = segmentTree[p].Left + (segmentTree[p].Right - segmentTree[p].Left) / 2;
if (l <= mid) SegT_Change(l, r, SegT_L(p), v);
if (mid < r) SegT_Change(l, r, SegT_R(p), v);
SegT_Update(p);
return;
}
public long AskSum(int l, int r, int p = 1)
{
if (l <= segmentTree[p].Left && segmentTree[p].Right <= r)
{
return segmentTree[p].Sum;
}
SegT_Spread(p);
long ans = 0;
int mid = segmentTree[p].Left + (segmentTree[p].Right - segmentTree[p].Left) / 2;
if (l <= mid) ans += AskSum(l, r, SegT_L(p));
if (mid < r) ans += AskSum(l, r, SegT_R(p));
SegT_Update(p);
return ans;
}
public long AskMax(int l, int r, int p = 1)
{
if (l <= segmentTree[p].Left && segmentTree[p].Right <= r)
{
return segmentTree[p].Max;
}
SegT_Spread(p);
long ans = long.MinValue;
int mid = segmentTree[p].Left + (segmentTree[p].Right - segmentTree[p].Left) / 2;
if (l <= mid) ans = Math.Max(ans, AskMax(l, r, SegT_L(p)));
if (mid < r) ans = Math.Max(ans, AskMax(l, r, SegT_R(p)));
SegT_Update(p);
return ans;
}
public long AskMin(int l, int r, int p = 1)
{
if (l <= segmentTree[p].Left && segmentTree[p].Right <= r)
{
return segmentTree[p].Min;
}
SegT_Spread(p);
long ans = long.MaxValue;
int mid = segmentTree[p].Left + (segmentTree[p].Right - segmentTree[p].Left) / 2;
if (l <= mid) ans = Math.Min(ans, AskMin(l, r, SegT_L(p)));
if (mid < r) ans = Math.Min(ans, AskMin(l, r, SegT_R(p)));
SegT_Update(p);
return ans;
}
}
Suffix array
class SuffixArray
{
public int[] Height = null, SA = null, Rank = null;
private int[] countSort = null, tp = null, digitArray = null;
int n, maxN = 127;
public SuffixArray(int[] array)
{
n = array.Length;
Height = new int[n + 1];
SA = new int[n + 1];
Rank = new int[n + 1];
digitArray = new int[n + 1];
for (int i = 0; i < n; i++)
{
digitArray[i + 1] = array[i];
if (maxN < array[i]) maxN = array[i];
}
countSort = new int[maxN + 1];
tp = new int[n + 1];
Suffix();
}
public SuffixArray(string array)
{
n = array.Length;
Height = new int[n + 1];
SA = new int[n + 1];
Rank = new int[n + 1];
digitArray = new int[n + 1];
for (int i = 0; i < n; i++)
{
digitArray[i + 1] = array[i];
if (maxN < array[i]) maxN = array[i];
}
countSort = new int[maxN + 1];
tp = new int[n + 1];
Suffix();
}
private void RSort()
{
for (int i = 0; i <= maxN; i++) countSort[i] = 0;
for (int i = 1; i <= n; i++) countSort[Rank[tp[i]]]++;
for (int i = 1; i <= maxN; i++) countSort[i] += countSort[i - 1];
for (int i = n; i >= 1; i--) SA[countSort[Rank[tp[i]]]--] = tp[i];
}
private bool cmp(int[] f, int x, int y, int w) { return f[x] == f[y] && f[x + w] == f[y + w]; }
private void Suffix()
{
for (int i = 1; i <= n; i++)
{
Rank[i] = digitArray[i];
tp[i] = i;
}
RSort();
for (int w = 1, p = 1, i; p < n; w += w, maxN = p)
{
for (p = 0, i = n - w + 1; i <= n; i++) tp[++p] = i;
for (i = 1; i <= n; i++) if (SA[i] > w) tp[++p] = SA[i] - w;
RSort();
int[] temp = Rank;
Rank = tp;
tp = temp;
Rank[SA[1]] = p = 1;
for (i = 2; i <= n; i++) Rank[SA[i]] = cmp(tp, SA[i], SA[i - 1], w) ? p : ++p;
}
int j, k = 0;
for (int i = 1; i <= n; Height[Rank[i++]] = k)
for (k = k != 0 ? k - 1 : k, j = SA[Rank[i] - 1]; digitArray[i + k] == digitArray[j + k]; ++k) ;
}
}
Basic operations on Binary Tree
Traverse by level
IList<IList<int>> TraByLevelOrder = null;
public void Traverse(TreeNode node, int level)
{
if (node == null)
return;
if (TraByLevelOrder.Count - 1 >= level)
{
if (node.left != null)
TraByLevelOrder[level].Add(node.left.val);
if (node.right != null)
TraByLevelOrder[level].Add(node.right.val);
}
else
{
IList<int> list = new List<int>();
if (node.left != null)
list.Add(node.left.val);
if (node.right != null)
list.Add(node.right.val);
if (list.Count > 0)
TraByLevelOrder.Add(list);
}
Traverse(node.left, level + 1);
Traverse(node.right, level + 1);
}
Find Kth Smallest Element in a BST