Problem:
Score : 500 points

Problem Statement

You have a string A = A_1 A_2 ... A_n consisting of lowercase English letters.

You can choose any two indices i and j such that 1 \leq i \leq j \leq n and reverse substring A_i A_{i+1} ... A_j.

You can perform this operation at most once.

How many different strings can you obtain?

Constraints

1 \leq |A| \leq 200,000

A consists of lowercase English letters.

Input

Input is given from Standard Input in the following format:

A

Output

Print the number of different strings you can obtain by reversing any substring in A at most once.

Sample Input 1

aatt

Sample Output 1

5

You can obtain aatt (don't do anything), atat (reverse A[2..3]), atta (reverse A[2..4]), ttaa (reverse A[1..4]) and taat (reverse A[1..3]).

Sample Input 2

xxxxxxxxxx

Sample Output 2

1

Whatever substring you reverse, you'll always get xxxxxxxxxx.

Sample Input 3

abracadabra

Sample Output 3

44

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Linq;//リストの使用
using System.Collections.Generic;
class Program
{
	static void Main()
	{
    string s = Console.ReadLine();
		long answer = 0;
    int[] oddMemo = PalindromeRadius(s);
    int[] evenMemo = PalindromeRadiusEven(s);
    for(long i = 0; i < s.Length-1; i++)
    {
      answer += oddMemo[i]-1;
      //Console.WriteLine(answer);
      answer += evenMemo[i]/2;
      //Console.WriteLine(answer);
    }
    answer += oddMemo[s.Length-1]/2;
    //Console.WriteLine(answer);
    answer = s.Length*(s.Length-1)/2 + 1 - answer;
    
		Console.WriteLine(answer);
	}

  static int[] PalindromeRadius(string aimString)
  //文字列から、O(n)でi文字目を中心とした「奇数長」の最長回文の半径(1,2,...)を返す
  {
    int[] answer = new int[aimString.Length];
    int lookChara = 0;
    int radiusMemo = 0;
    while(lookChara < aimString.Length)
    {
      while(lookChara-radiusMemo >= 0 && lookChara+radiusMemo < aimString.Length
        && aimString[lookChara-radiusMemo] == aimString[lookChara+radiusMemo]) radiusMemo++;
      answer[lookChara] = radiusMemo;
      int memo = 1;
      while(lookChara-memo >= 0 && lookChara+memo < aimString.Length &&
        answer[lookChara-memo]+memo < radiusMemo)
      {
        answer[lookChara+memo] = answer[lookChara+memo];
        memo++;
      }
      lookChara += memo;
      radiusMemo -= memo;
    }
  return answer;
  }

  static int[] PalindromeRadiusEven(string aimString)
  //i文字目（右端を除く）の右を中心とした「偶数長」の最長回文の半径(0,2,4...)を返す
  {
    string nextString = "";//調べる文字列。例えば"abc"なら"a#b#c"に変える。
    for(int i = 0; i < aimString.Length; i++)
    {
      nextString += aimString[i];
      if(i != aimString.Length-1) nextString += "#";
    }
    Console.WriteLine(nextString);
    int[] memo = PalindromeRadius(nextString);
    //Console.WriteLine(memo[0]+" "+memo[2]+" "+memo[4]);
    int[] answer = new int[aimString.Length-1];
    for(int i = 0; i < aimString.Length-1; i++)
    {
      answer[i] = memo[2*i+1];
      if(answer[i] % 2 == 1) answer[i]--;
    }
    return answer;
  }
  
}