Problem:
Score : 400 points

Problem Statement

One day, Snuke was given a permutation of length N, a_1, a_2, ..., a_N, from his friend.

Find the following:

Constraints

1 ≦ N ≦ 200,000

(a_1, a_2, ..., a_N) is a permutation of (1, 2, ..., N).

Input

The input is given from Standard Input in the following format:

N
a_1 a_2 ... a_N

Output

Print the answer.

Note that the answer may not fit into a 32-bit integer.

Sample Input 1

3
2 1 3

Sample Output 1

9

Sample Input 2

4
1 3 2 4

Sample Output 2

19

Sample Input 3

8
5 4 8 1 2 6 7 3

Sample Output 3

85

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using static MyIO;


public class B
{
	public static void Main()
	{
		(new Solver()).Solve();
	}
}


public struct Range
{
	public int L;
	public int R;

	public Range(int l, int r)
	{
		L = l;
		R = r;
	}
}


public class Solver
{
	private int N;
	private int[] a;
	private int[] inv;
	private SegmentTree<int> st;

	public Solver()
	{
		N = GetInt();
		a = new int[N];
		for(int i = 0; i < N; i++)
			a[i] = GetInt() - 1;

		inv = new int[N];
		for(int i = 0; i < N; i++)
			inv[a[i]] = i;

		st = new SegmentTree<int>(N, int.MaxValue, (x, y) => (int)Math.Min(x, y));
		for(int i = 0; i < N; i++)
			st.Update(i, a[i]);
	}

	public void Solve()
	{
		long ans = 0;
		var queue = new Queue<Range>();
		queue.Enqueue(new Range(0, N));
		while(queue.Count > 0)
		{
			var range = queue.Dequeue();
			int l = range.L;
			int r = range.R;

			int min = st.Query(l, r);
			int i = inv[min];
			ans += (long)(min + 1) * (long)(i - l + 1) * (long)(r - i);

			if(i > l)
				queue.Enqueue(new Range(l, i));

			if(i + 1 < r)
				queue.Enqueue(new Range(i + 1, r));		
		}
		Console.WriteLine(ans);
	}
}


public class SegmentTree<T>
{
	private int N;
	private T INI;
	private Func<T, T, T> Func;
	private T[] dat;

	public SegmentTree(int n, T ini, Func<T, T, T> func)
	{
		N = 1;		
		while(N < n)
			N <<= 1;

		INI = ini;
		Func = func;
			
		dat = new T[2 * N - 1];
		for(int i = 0; i < 2 * N - 1; i++)
			dat[i] = INI;
	}

	public void Update(int k, T a)
	{
		k += N - 1;
		dat[k] = a;
		while(k > 0)
		{
			k = (k - 1) / 2;
			dat[k] = Func(dat[k * 2 + 1], dat[k * 2 + 2]);
		}
	}

	public T Query(int a, int b, int k = 0, int l = 0, int r = -1)
	{
		if(r == -1)
			r = N;

		if(r <= a || b <= l)
			return INI;

		if(a <= l && r <= b)
			return dat[k];
		else
		{
			T vl = Query(a, b, k * 2 + 1, l, (l + r) / 2);
			T vr = Query(a, b, k * 2 + 2, (l + r) / 2, r);
			return Func(vl, vr);
		}
	}
}


public static class MyIO
{
	private static string[] args = null;
	private static int num = -1;
	private static int used = -1;

	private static string getArg()
	{
		if(used == num)
		{
			args = Console.ReadLine().Split(' ');
			num = args.Length;
			used = 0;
		}
		return args[used++];
	}

	public static int GetInt(){ return int.Parse(getArg()); }
	public static long GetLong(){ return long.Parse(getArg()); }
	public static double GetDouble(){ return double.Parse(getArg()); }
	public static string GetString(){ return getArg(); }
}