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.Linq;//リストの使用
using System.Collections.Generic;
using System.Text;//テキストの高速出力に必要
class Program
{
static long n = long.Parse(Console.ReadLine());//long.Parseはstringをlongに変換。
static long[] nums = Array.ConvertAll(Console.ReadLine().Split(' '),long.Parse);
static long[] positions = new long[n];//それぞれの数字が左から何番目か
static long[] bits = new long[n+2];
static long middleNum = 0;
static long answer = 0;

	static void Main()
	{
    for(int i = 0; i < n; i++)
    {
      positions[nums[i]-1] = i;
    }

    for(int i = 0; i < n; i++)
    {
      middleNum = positions[i];
      long leftCount = SearchLeft(0,positions[i]);
      long rightCount = SearchRight(0,n-1-positions[i]);
      //Console.WriteLine(leftCount+" "+rightCount +" "+ answer);
      answer += (i+1)*(leftCount+1)*(rightCount+1);//数　×　数が加算される部分列の個数
      BitAdd(positions[i]+1,1);//使用位置を1にする
    }
    
		Console.WriteLine(answer);
	}

  static void BitAdd(long i, long x)//BITでiだけにx加算
  {
    while(i <= n)
    {
      bits[i] += x;
      i += i&-i;
    }
  }

  static long BitSum(long i)//BITでi以下の総和を計算
  {
    long sum = 0;
    while(i > 0)
    {
      sum += bits[i];
      i -= i&-i;
    }
    return sum;
  }

  static long SearchLeft(long min, long max)//二分探索法で最大値を求める
  {
    while (true)
    {
      long mid = min + (max - min) / 2;
      if(CheckLeft(mid)) min = mid;//さらに大きくても成り立つかも
      else max = mid;

      if(max - min <= 1)
      {
        if(CheckLeft(max)) 
        {
          return max;//最大値で成り立つかの確認を優先
        }
        else
        {
          return min;
        }
      break;
      }  
    }
  }

  static long SearchRight(long min, long max)//二分探索法で最大値を求める
  {
    while (true)
    {
      long mid = min + (max - min) / 2;
      if(CheckRight(mid)) min = mid;//さらに大きくても成り立つかも
      else max = mid;

      if(max - min <= 1)
      {
        if(CheckRight(max)) 
        {
          return max;//最大値で成り立つかの確認を優先
        }
        else
        {
          return min;
        }
      break;
      }  
    }
  }

  static bool CheckLeft(long testNum)
  {
    if(BitSum(middleNum) - BitSum(middleNum-testNum) == 0) return true;
    return false;
  }

  static bool CheckRight(long testNum)
  {
    if(BitSum(middleNum+1+testNum) - BitSum(middleNum+1) == 0) return true;
    return false;
  }
  
}