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 Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)


import java.io.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.StringTokenizer;

public class Main {

    void solve() {
        String input = in.nextToken();
        StringBuilder sb = new StringBuilder();
        int[] index = new int[input.length()];
        for(int i = 0; i < index.length ; i++) {
            index[i] = i;
        }
        HashSet<String> result = new HashSet<>();
        result.add(input);
        for(int i = 0 ; i < index.length-1 ; i++) {
            for(int j = i+1 ; j < index.length ; j++) {
                int[] index_changed = reverse(index, i, j);
                Arrays.stream(index_changed).forEach(value ->
                        sb.append(input.charAt(value)));
                result.add(sb.toString());
                sb.delete(0, sb.length());

            }
        }
        out.println(result.size());

    }
    private int[] reverse(int[] index, int start, int end) {
        int[] changed = index.clone();
        for(int i = 0 ; i <= (end - start)/2 ; i++) {
            int temp = changed[start + i];
            changed[start + i] = changed[end - i];
            changed[end - i] = temp;
        }
        return changed;
    }



    FastScanner in;
    PrintWriter out;

    void run() {
        in = new FastScanner();
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    public class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        public FastScanner(String s) {
            try {
                br = new BufferedReader(new FileReader(s));
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }

        public String nextToken() {
            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                }
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(nextToken());
        }

        public long nextLong() {
            return Long.parseLong(nextToken());
        }

        public double nextDouble() {
            return Double.parseDouble(nextToken());
        }
    }

    public static void main(String[] args) {
        new Main().run();
    }

}