// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD = 1000000007LL;

// 区間を set で管理するやつ
// 閉区間 [l, r] を扱うことに注意
template <typename numericType, numericType infty = numeric_limits<numericType>::max() >
struct IntervalSet : set< pair<numericType, numericType> > {
    // x を含む閉区間 [l, r] を取得
    // イテレータを返す
    auto get(numericType x) {
        // x より始点が大きい区間の中で最小のもの
        auto itr = this->upper_bound(make_pair(x, infty));
        if(itr == this->begin() or (--itr)->second < x) return this->end();
        return itr;
    }

    // [l, r] と overlap する区間の集合を取得
    // vector を返す
    vector< pair<numericType, numericType> > get(numericType l, numericType r) {
        auto itr = this->upper_bound(make_pair(l, l));
        if(itr != this->begin()) itr--;

        vector< pair<numericType, numericType> > res;
        for(; itr != this->end(); itr++) {
            numericType il, ir; tie(il, ir) = *itr;
            if(r < il) break; // 対称区間に対して右に飛び出た
            // 対称区間に対して左に飛び出るか、含まれているかしかない
            if(ir >= l) res.push_back(make_pair(il, ir));
        }
        return res;
    }
    
    void insert(numericType l, numericType r) {
        auto vec = this->get(l, r);
        numericType il = l, ir = r;
        for(auto e : vec) {
            this->erase(e);
            il = min(il, e.first);
            ir = max(ir, e.second);
        }
        this->emplace(il, ir);
    }
    
    void remove(numericType l, numericType r) {
        auto vec = this->get(l, r);
        for(auto e : vec) this->erase(e);
    }

    // p と q は同じ区間上にあるか？
    bool same(numericType p, numericType q) {
        auto itr = get(p);
        return itr != this->end() and itr->first <= q and q <= itr.second;
    }

    void dump() {
        for(auto e : *this) {
            numericType l, r; tie(l, r) = e;
            fprintf(stderr, "# debug: [%g, %g]\n", l, r);
        }
    }
};


ll solve(ll N, ll X, ll D) {
    fprintf(stderr, "N = %lld, X = %lld, D = %lld\n", N, X, D);
    if(X == 0 and D == 0) return 1LL;
    if(D == 0) return N + 1;
    if(D < 0) {
        X += D * (N - 1);
        return solve(N, X, -D);
    }

    // D > 0 としてよい
    // A_i = X + iD (0-indexed)
    // 1X + kD (0 <= k <= N-1)
    // 2X + kD (1 <= k <= 2N-3)
    // 3X + kD (3 <= k <= 3N-6) ...
    // iX + kD ( i*(i-1)/2 <= k <= i*N-i*(i+1)/2 )
    // fprintf(stderr, "N = %lld, X = %lld, D = %lld\n", N, X, D);
    
    ll ans = 0;
    map< ll, IntervalSet<ll> > mods;
    for(ll i=0; i<=N; i++) {
        ll lb = i*(i-1)/2, ub = i*N-i*(i+1)/2;
        if(lb > ub) swap(lb, ub);
        ll m = (X * i) % D, d = (X * i) / D;
        if(m < 0) d--, m += D;
        lb += d, ub += d;
        // fprintf(stderr, "m = %lld, lb = %lld, ub = %lld\n", m, lb, ub);
        
        mods[m].insert(lb, ub);

        /*
        if(mod_l.count(m)) {
            if(mod_u[m] <= lb) ans += ub - lb + 1;
            else if(ub <= mod_l[m]) ans += ub - lb + 1;
            else {
                if(mod_u[m] <= ub) ans += ub - mod_u[m] + 1;
                if(lb <= mod_l[m]) ans += mod_l[m] - lb + 1;
            }
            chmax(mod_u[m], ub + 1);
            chmin(mod_l[m], lb - 1);
        }
        else {
            ans += ub - lb + 1;
            mod_u[m] = ub + 1;
            mod_l[m] = lb - 1;
        }
        */
    }

    for(auto m : mods) {
        for(auto s : m.second) {
            ll l, r; tie(l, r) = s;
            ans += r - l + 1;
        }
    }
    return ans;
}

int main() {
    ll N, X, D; cin >> N >> X >> D;
    cout << solve(N, X, D) << endl;
    return 0;
}


Measured memory_bytes: 31488