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 Rust (1.15.1) (judge verdict: Accepted)

use std::collections::HashMap;
use std::collections::btree_map::Entry;
use std::collections::BTreeMap;
use std::cmp::max;

#[derive(Debug, PartialEq)]
struct Section {
    a: i64,
    b: i64
}

impl Section {
    fn new(a: i64, b: i64) -> Section {
        Section { a: a, b: b }
    }

    pub fn len(&self) -> i64 {
        self.b - self.a + 1
    }
}

struct SectionList {
    map: BTreeMap<i64, i64>
}

impl SectionList {
    fn new () -> SectionList {
        SectionList { map: BTreeMap::new() }
    }

    fn insert(&mut self, a: i64, b: i64) {
        assert!(a <= b);
        match self.map.entry(a) {
            Entry::Occupied(mut x) => {
                let value = x.get_mut();
                *value = max(*value, b);
            },
            Entry::Vacant(x) => {
                x.insert(b);
            }
        };
    }

    fn merge(&self) -> Vec<Section> {
        match self.map.len() {
            0 => vec![],
            1 => {
                let mut iter = self.map.iter();
                let (a, b) = iter.next().unwrap();
                vec![Section::new(*a, *b)]
            },
            _ => {
                let mut iter = self.map.iter();
                let (mut current_a, mut current_b) = iter.next().unwrap();
                let mut result = vec![];
                for (a, b) in iter {
                    if a <= &(current_b + 1) {
                        current_b = max(b, current_b);
                    } else {
                        result.push(Section::new(*current_a, *current_b));
                        current_a = a;
                        current_b = b;
                    }
                }
                result.push(Section::new(*current_a, *current_b));
                result
            }
        }
    }
}

fn len_sum(sections: Vec<Section>) -> i64 {
    sections.iter().fold(0, |sum, section| { section.len() + sum })
}

fn solve(n: i64, mut x: i64, mut d: i64) -> i64 {
    if d == 0 {
        if x == 0 {
            return 1;
        } else {
            return n + 1;
        }
    }

    if d < 0 {
        d = -d;
        x = -x;
    }

    let d = d;
    let x = x;

    let mut map = HashMap::new();

    for k in 0 .. n + 1 {
        let a = (k * (k - 1)) / 2;
        let b = k * (2 * n - k - 1) / 2;

        let (q, r) = if x < 0 {
            let kx = -x * k;
            (-(kx / d), kx % d)
        } else {
            let kx = x * k;
            (kx / d, kx % d)
        };

        map.entry(r).or_insert(SectionList::new()).insert(a + q, b + q);
    }

    map.iter().fold(0, |sum, (_key, section_list)| {
        sum + len_sum(section_list.merge())
    })
}

fn main() {
    let (n, x, d): (i64, i64, i64) = {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        let mut s = s.trim().split_whitespace();
        (s.next().unwrap().trim().parse().unwrap(), s.next().unwrap().trim().parse().unwrap(), s.next().unwrap().trim().parse().unwrap())
    };

    print!("{}", solve(n, x, d));
}