Problem:
Score : 400 points

Problem Statement

We have N balls. The i-th ball has an integer A_i written on it.

For each k=1, 2, ..., N, solve the following problem and print the answer.

Find the number of ways to choose two distinct balls (disregarding order) from the N-1 balls other than the k-th ball so that the integers written on them are equal.

Constraints

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

1 \leq A_i \leq N

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

For each k=1,2,...,N, print a line containing the answer.

Sample Input 1

5
1 1 2 1 2

Sample Output 1

2
2
3
2
3

Consider the case k=1 for example. The numbers written on the remaining balls are 1,2,1,2.

From these balls, there are two ways to choose two distinct balls so that the integers written on them are equal.

Thus, the answer for k=1 is 2.

Sample Input 2

4
1 2 3 4

Sample Output 2

0
0
0
0

No two balls have equal numbers written on them.

Sample Input 3

5
3 3 3 3 3

Sample Output 3

6
6
6
6
6

Any two balls have equal numbers written on them.

Sample Input 4

8
1 2 1 4 2 1 4 1

Sample Output 4

5
7
5
7
7
5
7
5

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace AtCoderPractice
{
    class Program
    {


        /// <summary>
        /// 順列 (n >= k)
        /// </summary>
        public static long nPk(long n, long k)
        {
            if (n < k) return 0;
            if (n == k) return 1;

            long x = 1;
            for (long i = 0; i < k; i++)
            {
                x = x * (n - i);
            }
            return x;
        }

        public static Dictionary<Tuple<long, long>, long> nCkDic = new Dictionary<Tuple<long, long>, long>();
        /// <summary>
        /// 組み合わせ (n >= k)
        /// </summary>
        public static long nCk(long n, long k)
        {
            if (n < k) return 0;
            if (n == k) return 1;

            if (nCkDic.ContainsKey(new Tuple<long, long>(n,k))) return nCkDic[new Tuple<long, long>(n, k)];

            long x = 1;
            for (long i = 0; i < k; i++)
            {
                x = x * (n - i) / (i + 1);
            }

            nCkDic[new Tuple<long, long>(n, k)] = x;
            return x;
        }

        const string AZ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        static void Main(string[] args)
        {
            var r = "";
            var b = false;
            var count = 0l;
            var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
            Console.SetOut(sw);

            // 処理





            // なんこあるか
            var k = StandardInputToLong();
            var vs = StandardInputToLongs();

            for (var i = 0; i < k; i++) {
                count = AllPairCount(vs);
                count += (int)nCk(vs.Count(n => n == vs[i]) - 1, 2) - dic[(int)vs[i]];
                r += count.ToString() + Environment.NewLine;
            }



            // 処理

            //Console.WriteLine($"{(b ? "Yes" : "No")}");
            Console.WriteLine($"{r}");


            // 処理終了
            Console.Out.Flush();
            Console.ReadKey();
        }


        public static Dictionary<int, int> dic = new Dictionary<int, int>();
        static long pairCount;
        public static long AllPairCount(IList<long> vs)
        {
            if (pairCount != 0) return pairCount;
            var r = 0;
            var i = 0;
            foreach(var v in vs.GroupBy(n => n).Select(n => n.Key))
            {
                r += PairCount(vs, (int)v);
                i++;
            }
            pairCount = r;
            return pairCount;
        }
        public static int PairCount(IList<long> vs, int v)
        {
            if (dic.ContainsKey(v)) return dic[v];
            var r = nCk(vs.Count(n => n == v), 2);
            dic[v] = (int)r;
            return dic[v];
        }



        /*
        static long max;
        public static void Set(long v)
        {
            if (max < v) max = v;
        }

        Dictionary<(int, int), long> dic = new Dictionary<(int, int), long>();

        public static void dp(long)
        */







        static bool isKaibun(string v)
        {
            int i = v.Length - 1;
            foreach(var c in v)
            {
                if(c != v[i])
                {
                    return false;
                }
                i--;
            }

            return true;
        }

        public static decimal Sqrt(decimal x, decimal? guess = null)
        {
            var ourGuess = guess.GetValueOrDefault(x / 2m);
            var result = x / ourGuess;
            var average = (ourGuess + result) / 2m;

            if (average == ourGuess) // This checks for the maximum precision possible with a decimal.
                return average;
            else
                return Sqrt(x, average);
        }

        #region 標準処理ライブラリ
        /// <summary>
        /// 半角スペース区切りの標準入力を文字列のIListに変換します。
        /// </summary>
        /// <returns></returns>
        static public IList<string> StandardInputToStrings()
        {
            return Console.ReadLine().Split(' ').ToList();
        }

        /// <summary>
        /// stringを取得
        /// </summary>
        /// <returns></returns>
        static public string StandardInputToString()
        {
            return Console.ReadLine();
        }

        /// <summary>
        /// 半角スペース区切りの標準入力を文字列のIListに変換します。複数行に対応。
        /// </summary>
        /// <returns></returns>
        static public IList<IList<string>> MultipleStandardInputToStrings()
        {
            string line;
            var r = new List<List<string>>();
            do
            {
                line = Console.ReadLine();
                r.Add(line.Split(' ').ToList());
                line = Console.ReadLine();
            } while (line == null);

            return (IList<IList<string>>)r;
        }

        /// <summary>
        /// 半角スペース区切りの標準入力を数値のIListに変換します。
        /// </summary>
        /// <returns></returns>
        static public IList<long> StandardInputToLongs()
        {
            return Console.ReadLine().Split(' ').Select(n => long.Parse(n)).ToList();
        }
        /// <summary>
        /// 半角スペース区切りの標準入力を数値のIListに変換します。
        /// </summary>
        /// <returns></returns>
        static public long StandardInputToLong()
        {
            return long.Parse(Console.ReadLine());
        }

        /// <summary>
        /// 半角スペース区切りの標準入力を文字列のIListに変換します。複数行に対応。
        /// </summary>
        /// <returns></returns>
        static public IList<IList<long>> MultipleStandardInputToLongs()
        {
            string line;
            var r = new List<List<long>>();
            do
            {
                line = Console.ReadLine();
                r.Add(line.Split(' ').Select(n => long.Parse(n)).ToList());
                line = Console.ReadLine();
            } while (line == null);

            return (IList<IList<long>>)r;
        }

        /// <summary>
        /// 半角スペース区切りの標準入力を数値のIListに変換します。
        /// </summary>
        /// <returns></returns>
        static public IList<int> StandardInputToInts()
        {
            return Console.ReadLine().Split(' ').Select(n => int.Parse(n)).ToList();
        }
        /// <summary>
        /// 半角スペース区切りの標準入力を数値のIListに変換します。
        /// </summary>
        /// <returns></returns>
        static public int StandardInputToInt()
        {
            return int.Parse(Console.ReadLine());
        }

        /// <summary>
        /// 半角スペース区切りの標準入力を文字列のIListに変換します。複数行に対応。
        /// </summary>
        /// <returns></returns>
        static public IList<IList<int>> MultipleStandardInputToInts()
        {
            string line;
            var r = new List<List<int>>();
            do
            {
                line = Console.ReadLine();
                r.Add(line.Split(' ').Select(n => int.Parse(n)).ToList());
                line = Console.ReadLine();
            } while (line == null);

            return (IList<IList<int>>)r;
        }
    }






    public static class AtCoderResultExtentions
    {
        static public string AsDelimitedResult<T>(this IList<T> ie, string delimitter = " ")
        {
            return string.Join(delimitter, ie);
        }
    }
    #endregion
    #region List拡張
    public static class IListExtensions
    {


        public static IEnumerable<IEnumerable<T>> Perm<T>(this IEnumerable<T> items, int? k = null)
        {
            if (k == null)
                k = items.Count();

            if (k == 0)
            {
                yield return Enumerable.Empty<T>();
            }
            else
            {
                var i = 0;
                foreach (var x in items)
                {
                    var xs = items.Where((_, index) => i != index);
                    foreach (var c in Perm(xs, k - 1))
                        yield return c.Before(x);

                    i++;
                }
            }
        }
        public static IEnumerable<IEnumerable<T>> Comb<T>(this IEnumerable<T> items, int r)
        {
            if (r == 0)
            {
                yield return Enumerable.Empty<T>();
            }
            else
            {
                var i = 1;
                foreach (var x in items)
                {
                    var xs = items.Skip(i);
                    foreach (var c in Comb(xs, r - 1))
                        yield return c.Before(x);

                    i++;
                }
            }

        }

        // 要素をシーケンスに追加するユーティリティ
        public static IEnumerable<T> Before<T>(this IEnumerable<T> items, T first)
        {
            yield return first;

            foreach (var i in items)
                yield return i;
        }
        public static IList<T> Swap<T>(this IList<T> ie, int indexA, int indexB)
        {
            var temp = ie[indexA];
            ie[indexA] = ie[indexB];
            ie[indexB] = temp;
            return ie;
        }
    }
    #endregion
}