Templates of basic data structures

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()
    {
        //SA
        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;
        }
        //Height
        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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值