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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)


import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
import java.util.Scanner;

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

	void run() {
		Scanner sc = new Scanner(System.in);
		long N = sc.nextLong();
		long X = sc.nextLong();
		long D = sc.nextLong();
		solve(N,X,D);
	}

	final long MOD = (long) (1e9 + 7);

	void solve(long N, long X, long D) {
		if (D < 0) {
			X *= -1;
			D *= -1;
		} else if (D == 0) {
			// A(i)=X(const)
			if (X == 0) {
				System.out.println(1);
			} else {
				System.out.println(N + 1);
			}
			return;
		}
		// A(i)=D(i-1)+X
		HashSet<Long> set = new HashSet<>();
		for (int i = 1; i <= N; ++i) {
			set.add(X * i % D);
		}
		set.add(0L);
		long[] id = new long[set.size()];
		int p = 0;
		for (long v : set) {
			id[p++] = v;
		}
		Arrays.sort(id);
		PriorityQueue<long[]>[] pq = new PriorityQueue[set.size()];
		for (int i = 0; i < pq.length; ++i) {
			pq[i] = new PriorityQueue<long[]>(new Comparator<long[]>() {
				@Override
				public int compare(long[] o1, long[] o2) {
					if (o1[0] != o2[0]) {
						return Long.compare(o1[0], o2[0]); // start, end
					} else {
						return Long.compare(o1[1], o2[1]);
					}
				}
			});
		}
		long ans = 0;
		for (int i = 1; i <= N; ++i) {
			long mod = X * i % D;
			int idx = Arrays.binarySearch(id, mod);
			if (idx < 0)
				throw new AssertionError();
			long start = i * (i - 1) / 2;// 0+1+...+i-1=(1/2)i(i-1)
			long end = N * i - i * (i + 1) / 2;// (n-i)...+(n-2)+(n-1)=ni-i(i+1)/2
			pq[idx].add(new long[] { start * D + X * i, end * D + X * i });
		}
		pq[0].add(new long[] { 0, 0 });
		for (int i = 0; i < pq.length; ++i) {
			while (!pq[i].isEmpty()) {
				long[] a = pq[i].poll();
				while (!pq[i].isEmpty() && a[1] >= pq[i].peek()[0]) {
					if (a[1] > pq[i].peek()[1]) {
						pq[i].poll();
					} else {
						long[] b = pq[i].poll();
						a[1] = b[1];
					}
				}
				ans += (a[1] - a[0] + D) / D;
			}
		}
		// 0,4,6,8,10,12,14,18
		System.out.println(ans);
	}

	void tr(Object... objects) {
		System.out.println(Arrays.deepToString(objects));
	}

}