Problem:
Score : 700 points

Problem Statement

There are N stones arranged in a row. The i-th stone from the left is painted in the color C_i.

Snuke will perform the following operation zero or more times:

Choose two stones painted in the same color. Repaint all the stones between them, with the color of the chosen stones.

Find the number of possible final sequences of colors of the stones, modulo 10^9+7.

Constraints

1 \leq N \leq 2\times 10^5

1 \leq C_i \leq 2\times 10^5(1\leq i\leq N)

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
C_1
:
C_N

Output

Print the number of possible final sequences of colors of the stones, modulo 10^9+7.

Sample Input 1

5
1
2
1
2
2

Sample Output 1

3

We can make three sequences of colors of stones, as follows:

(1,2,1,2,2), by doing nothing.

(1,1,1,2,2), by choosing the first and third stones to perform the operation.

(1,2,2,2,2), by choosing the second and fourth stones to perform the operation.

Sample Input 2

6
4
2
5
4
2
4

Sample Output 2

5

Sample Input 3

7
1
3
1
2
3
3
2

Sample Output 3

5

Solution in C# (.NET Core 3.1.201) (judge verdict: Accepted)

using System;
using System.Text;
using System.Collections.Generic;
using System.Collections;
using static System.Math;
using System.Linq;
using static System.Array;

namespace ConsoleApp2
{
    public static class StringExtensions
    {
        public static string ToTitleCase(this string self)
        {
            return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(self);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //var N = long.Parse(Console.ReadLine());
            Solve();
            
        }
        static void Solve()
        {
            var N = long.Parse(Console.ReadLine());
            var dic = new Dictionary<long, long>();
            var Sum = new Modular(1);
            var pre = -1L;
            for (int i = 0; i < N; i++)
            {
                
                var num = long.Parse(Console.ReadLine());
                //if (i == 0)
                //{
                //    dic.Add(num, 0);
                //    continue;
                //}
                if (pre == num) continue;
                if (dic.ContainsKey(num))
                {
                    var tmp = Sum.value;
                    Sum += (dic[num]);
                    dic[num] = Sum.value;
                }
                else
                {
                    dic.Add(num, Sum.value);
                }
                pre = num;
            }
            
            Console.WriteLine(Sum.value);

        }



        class Treap<T> : IEnumerable<T> where T : IComparable
        {
            public int Length
            {
                get { return this.Root == null ? 0 : this.NodeCount(this.Root); }
            }
            public T this[int i]
            {
                get
                {
                    if (this.Root.Count < i - 1) throw new IndexOutOfRangeException();
                    return this.Root.Get(i);
                }
            }
            public Node Root;
            private IComparer<T> Cmp = Comparer<T>.Default;
            public Treap(IComparer<T> cmp = null)
            {
                if (cmp != null) this.Cmp = cmp;
            }
            public Node Merge(Node l, Node r)
            {
                if (l == null || r == null) return l == null ? r : l;

                if (l.Priority > r.Priority)
                {
                    l.R = this.Merge(l.R, r);
                    return this.Update(l);
                }
                else
                {
                    r.L = this.Merge(l, r.L);
                    return this.Update(r);
                }
            }
            // 左にk個、右に残り(n-k)個に分割する
            public (Node, Node) Split(int k) { return this.Split(this.Root, k); }
            public (Node, Node) Split(Node t, int k)
            {
                if (t == null) return (null, null);
                if (k <= this.NodeCount(t.L))
                {
                    var s = this.Split(t.L, k);
                    t.L = s.Item2;
                    return (s.Item1, this.Update(t));
                }
                else
                {
                    var s = this.Split(t.R, k - this.NodeCount(t.L) - 1);
                    t.R = s.Item1;
                    return (this.Update(t), s.Item2);
                }
            }
            public int NodeCount(Node node)
            {
                return node == null ? 0 : node.Count;
            }
            public int LowerBouond(T value) { return this.LowerBouond(this.Root, value); }
            public int LowerBouond(Node node, T value)
            {
                if (node == null) return 0;
                if (this.Cmp.Compare(value, node.Value) <= 0)
                    return this.LowerBouond(node.L, value);
                else
                    return this.NodeCount(node.L) + 1 + this.LowerBouond(node.R, value);
            }
            public int UpperBound(T value) { return this.UpperBound(this.Root, value); }
            public int UpperBound(Node node, T value)
            {
                if (node == null) return 0;
                if (this.Cmp.Compare(value, node.Value) >= 0)
                    return this.NodeCount(node.L) + 1 + this.UpperBound(node.R, value);
                else
                    return this.UpperBound(node.L, value);
            }
            public int ValueCount(T value)
            {
                return this.UpperBound(value) - this.LowerBouond(value);
            }
            public void Insert(T value)
            {
                var sub = this.Split(this.Root, this.LowerBouond(value));
                var newNode = new Node(value);
                var merged = this.Merge(sub.Item1, newNode);
                this.Root = this.Merge(merged, sub.Item2);
            }
            public void Erase(T value)
            {
                if (this.ValueCount(value) == 0) return;
                var sub = this.Split(this.Root, this.LowerBouond(value));
                this.Root = this.Merge(sub.Item1, this.Split(sub.Item2, 1).Item2);
            }
            public void InsertAt(Node node, int k)
            {
                var sub = this.Split(this.Root, k);
                var merged = this.Merge(sub.Item1, node);
                this.Root = this.Merge(merged, sub.Item2);
            }
            public void InsertAt(T value, int k)
            {
                var node = new Node(value);
                var sub = this.Split(this.Root, k);
                var merged = this.Merge(sub.Item1, node);
                this.Root = this.Merge(merged, sub.Item2);
            }
            public Node EraseAt(int k)
            {
                var sub = this.Split(this.Root, k);
                var sub2 = this.Split(sub.Item2, 1);
                var res = sub2.Item1;
                this.Root = this.Merge(sub.Item1, sub2.Item2);
                return res;
            }
            public Node Update(Node node)
            {
                node.Count = this.NodeCount(node.L) + this.NodeCount(node.R) + 1;
                return node;
            }
            public class Node
            {
                private static Random Rand = new Random();
                public T Value;
                public Node L = null;
                public Node R = null;
                public int Count;
                public double Priority;
                public Node(T value, double priority)
                {
                    this.Value = value;
                    this.Priority = priority;
                    this.Count = 1;
                }
                public Node(T value) : this(value, Rand.NextDouble()) { }
                public T Get(int i) { return this.GetNode(i).Value; }
                public Node GetNode(int i)
                {
                    var lcount = 0;
                    if (this.L != null) lcount = this.L.Count;
                    if (lcount == i) return this;
                    else if (lcount < i) return this.R.GetNode(i - lcount - 1);
                    else return this.L.GetNode(i);
                }
            }
            public IEnumerator<T> GetEnumerator()
            {
                for (int i = 0; i < this.Length; i++) yield return this.Root.Get(i);
            }
            IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
        }

    }

    class Modular
    {
        private const int M = 1000000007;
        public long value;
        public Modular(long value) { this.value = value; }
        public static implicit operator Modular(long a)
        {
            var m = a % M;
            return new Modular((m < 0) ? m + M : m);
        }
        public static Modular operator +(Modular a, Modular b)
        {
            return (a.value + b.value) % M;
        }
        public static Modular operator -(Modular a, Modular b)
        {
            return a.value - b.value;
        }
        public static Modular operator *(Modular a, Modular b)
        {
            return a.value * b.value;
        }
        public static Modular Pow(Modular a, int n)
        {
            switch (n)
            {
                case 0:
                    return 1;
                case 1:
                    return a;
                default:
                    var p = Pow(a, n / 2);
                    return p * p * Pow(a, n % 2);
            }
        }
        public static Modular operator /(Modular a, Modular b)
        {
            return a * Pow(b, M - 2);
        }
        private static readonly List<int> facs = new List<int> { 1 };
        private static Modular Fac(int n)
        {
            for (int i = facs.Count; i <= n; ++i)
            {
                facs.Add((int)(Math.BigMul(facs.Last(), i) % M));
            }
            return facs[n];
        }
        public static Modular Ncr(int n, int r)
        {
            return (n < r) ? 0
                 : (n == r) ? 1
                            : Fac(n) / (Fac(r) * Fac(n - r));
        }
        public static explicit operator int(Modular a)
        {
            return (int)a.value;
        }

        public static Modular Lcm(Modular a, Modular b)
        {
            var tmp = Gcdl(a.value, b.value);
            return ((a * b) / new Modular(tmp));
        }
        static Modular Gcd(Modular m, Modular n)
        {
            if (n.value > m.value) return Gcd(n, m);
            if (n.value == 0) return m;
            var r = new Modular(m.value % n.value);
            return Gcd(n, r);
        }

        static long Gcdl(long m, long n)
        {
            if (n > m) return Gcdl(n, m);
            if (n == 0) return m;
            return Gcdl(n, m % n);
        }
    }
}