Problem:
Score : 600 points

Problem Statement

We have an integer sequence A of length N, where A_1 = X, A_{i+1} = A_i + D (1 \leq i < N ) holds.

Takahashi will take some (possibly all or none) of the elements in this sequence, and Aoki will take all of the others.

Let S and T be the sum of the numbers taken by Takahashi and Aoki, respectively. How many possible values of S - T are there?

Constraints

-10^8 \leq X, D \leq 10^8

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

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N X D

Output

Print the number of possible values of S - T.

Sample Input 1

3 4 2

Sample Output 1

8

A is (4, 6, 8).

There are eight ways for (Takahashi, Aoki) to take the elements: ((), (4, 6, 8)), ((4), (6, 8)), ((6), (4, 8)), ((8), (4, 6))), ((4, 6), (8))), ((4, 8), (6))), ((6, 8), (4))), and ((4, 6, 8), ()).

The values of S - T in these ways are -18, -10, -6, -2, 2, 6, 10, and 18, respectively, so there are eight possible values of S - T.

Sample Input 2

2 3 -3

Sample Output 2

2

A is (3, 0). There are two possible values of S - T: -3 and 3.

Sample Input 3

100 14 20

Sample Output 3

49805

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static System.Console;
using static System.Math;

namespace AtTest.ABC_147
{
    class F
    {
        static void Main(string[] args)
        {
            var sw = new System.IO.StreamWriter(OpenStandardOutput()) { AutoFlush = false };
            SetOut(sw);

            Method(args);

            Out.Flush();
        }

        static void Method(string[] args)
        {
            long[] nxd = ReadLongs();
            long n = nxd[0];
            long x = nxd[1];
            long d = nxd[2];
            if (d == 0)
            {
                if (x == 0)
                {
                    WriteLine(1);
                }
                else
                {
                    WriteLine(n + 1);
                }
                return;
            }
            if (d < 0)
            {
                x *= -1;
                d *= -1;
            }
            long baseVal = long.MinValue / 10;
            long[][] ranges = new long[n+1][];
            long minVal = 0;
            long maxVal = 0;
            for(int i = 0; i <= n; i++)
            {
                long fixVal = x * i - baseVal;
                long margin = fixVal % d;
                long min = minVal + fixVal / d;
                long max = maxVal + fixVal / d;
                ranges[i] = new long[3] { margin, min, max };
                minVal += i;
                maxVal += n - i - 1;
            }
            ranges = ranges.OrderBy(a => a[1]).OrderBy(a => a[0]).ToArray();
            long res = 0;
            long prev = -1;
            long prevRight = 0;
            for(int i = 0; i <= n; i++)
            {
                if (ranges[i][0] != prev) prevRight = -1;
                prev = ranges[i][0];
                if (prevRight < ranges[i][1])
                {
                    res += ranges[i][2] - ranges[i][1] + 1;
                    prevRight = ranges[i][2];
                }
                else if(prevRight<ranges[i][2])
                {
                    res += ranges[i][2] - prevRight;
                    prevRight = ranges[i][2];
                }
            }
            WriteLine(res);
        }

        private static string Read() { return ReadLine(); }
        private static char[] ReadChars() { return Array.ConvertAll(Read().Split(), a => a[0]); }
        private static int ReadInt() { return int.Parse(Read()); }
        private static long ReadLong() { return long.Parse(Read()); }
        private static double ReadDouble() { return double.Parse(Read()); }
        private static int[] ReadInts() { return Array.ConvertAll(Read().Split(), int.Parse); }
        private static long[] ReadLongs() { return Array.ConvertAll(Read().Split(), long.Parse); }
        private static double[] ReadDoubles() { return Array.ConvertAll(Read().Split(), double.Parse); }
    }
}