Problem:
Score : 1000 points

Problem Statement

In a two-dimensional plane, we have a rectangle R whose vertices are (0,0), (W,0), (0,H), and (W,H), where W and H are positive integers.
Here, find the number of triangles \Delta in the plane that satisfy all of the following conditions:

Each vertex of \Delta is a grid point, that is, has integer x- and y-coordinates.

\Delta and R shares no vertex.

Each vertex of \Delta lies on the perimeter of R, and all the vertices belong to different sides of R.

\Delta contains at most K grid points strictly within itself (excluding its perimeter and vertices).

Constraints

1 \leq W \leq 10^5

1 \leq H \leq 10^5

0 \leq K \leq 10^5

Input

Input is given from Standard Input in the following format:

W H K

Output

Print the answer.

Sample Input 1

2 3 1

Sample Output 1

12

For example, the triangle with the vertices (1,0), (0,2), and (2,2) contains just one grid point within itself and thus satisfies the condition.

Sample Input 2

5 4 5

Sample Output 2

132

Sample Input 3

100 100 1000

Sample Output 3

461316

Solution in C# (Mono-csc 3.5.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCoder {
    class Triangles {
        static int gcd(int a, int b) {
            while (a>0 && b>0) {
                if (a>b) {
                    a %= b;
                } else {
                    b %= a;
                }
            }
            return a + b;
        }

        static int solve(int W, int H, int K) {
            int[] gcdMemo = new int[H + 1];
            for (int h = 0; h <= H; h++) {
                gcdMemo[h] = gcd(W, h);
            }

            int lim = 2 * K - 2;

            int ans = 0;
            for (int x = 1; x < W; x++) {
                for (int y1 = 1; y1 < H; y1++) {
                    if ((long)W * y1 - 2 * W > lim) {
                        break;
                    }

                    int g = -1;

                    for (int y2 = y1; y2 < H; y2++) {
                        if ((long)(W - x) * y1 + (long)x * y2 - 2 * W > lim) {
                            break;
                        }

                        if (g == -1) {
                            g = gcd(x, y1);
                        }

                        if ((W - x) * y1 + x * y2 - g - gcd(W - x, y2) - gcdMemo[Math.Abs(y1 - y2)] <= lim) {
                            ans += (y1 == y2 ? 1 : 2);
                        }
                    }
                }
            }
            return 2 * ans;
        }

        public static void Main(string[] args) {
            var parts = Console.ReadLine().Split(' ');
            int W = int.Parse(parts[0]);
            int H = int.Parse(parts[1]);
            int K = int.Parse(parts[2]);

            //Stopwatch tm = new Stopwatch();
            //tm.Start();
            int ans = solve(W, H, K) + solve(H, W, K);
            //tm.Stop();

            //Console.WriteLine(tm.ElapsedMilliseconds + " ms");
            Console.WriteLine(ans);
        }
    }
}