Language: C++

// Generated by 1.1.6 https://github.com/kyuridenamida/atcoder-tools

#include <bits/stdc++.h>

using namespace std;

using i64 = __int128_t;

const i64 MOD = 1e9 + 7;
const i64 INF = i64(1e18) + 7;


template <typename T>
bool chmin(T& x, T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& x, T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}


template<typename T, typename U>
struct Segtree{

    struct SegNode{
        T val;
        U lazy;

        SegNode* l;
        SegNode* r;
        SegNode(T val, U lazy) : val(val), lazy(lazy), l(nullptr), r(nullptr){}
    };

    i64 n;
    function<T(T, T)> f;
    function<T(T, U, i64)> g;
    function<U(U, U)> h;
    T op_t;
    U op_u;

    SegNode* root;

    Segtree(int n_, function<T(T, T)> f, function<T(T, U, i64)> g, function<U(U, U)> h, T op_t, U op_u) : f(f), g(g), h(h), op_t(op_t), op_u(op_u){
        for(n = 1; n < n_; n <<= 1);
        root = new SegNode(op_t, op_u);
    }

    SegNode* getl(SegNode* node){
        return node->l ? node->l : node->l = new SegNode(op_t, op_u);
    }

    SegNode* getr(SegNode* node){
        return node->r ? node->r : node->r = new SegNode(op_t, op_u);
    }

    void eval(SegNode* node, i64 len){
        node->val = g(node->val, node->lazy, len);
        getl(node);
        node->l->lazy = h(node->l->lazy, node->lazy);
        getr(node);
        node->r->lazy = h(node->r->lazy, node->lazy);
        node->lazy = op_u;
    }

    void update(i64 x, i64 y, U val, SegNode* node = nullptr, i64 l = 0, i64 r = 0){
        if(node == nullptr){
            node = root;
            r = n;
        }
        eval(node, r - l);
        if(r <= x || y <= l)
            return ;
        if(x <= l && r <= y){
            node->lazy = h(node->lazy, val);
            eval(node, r - l);
        }else{
            i64 mid = (l + r) >> 1;
            update(x, y, val, getl(node), l, mid);
            update(x, y, val, getr(node), mid, r);
            node->val = f(node->l->val, node->r->val);
        }
    }

    T get(i64 x, i64 y, SegNode* node = nullptr, i64 l = 0, i64 r = 0){
        if(node == nullptr){
            node = root;
            r = n;
        }

        if(r <= x || y <= l)
            return op_t;
        eval(node, r - l);
        if(x <= l && r <= y)
            return node->val;

        i64 val_l = op_t, val_r = op_t;
        i64 mid = (l + r) >> 1;

        if(node->l)
            val_l = get(x, y, node->l, l, mid);
        if(node->r)
            val_r = get(x, y, node->r, mid, r);
        return f(val_l, val_r);
    }

};

i64 mod(i64 x, i64 d){
    x = x + (-x + d - 1) / d * d;
    return x % d;
}

i64 body(i64 x, i64 d){
    if(x < 0)
        return -((-x + d - 1) / d);
    else
        return x / d;
}


void solve(long long _n, long long _x, long long _d){
    i64 n = _n, x = _x, d = _d;
    assert(x > 0 && d > 0);
    if(d == 0){
        cout << _n + 1 << endl;
        return;
    }
    if(d < 0){
        x += n * (n - 1) / 2 * d;
        d *= -1;
    }

    // [l, r]
    vector<i64> l(n + 1), r(n + 1);
    for(int i = 0; i < n; ++i){
        l[i + 1] = l[i] + i;
        r[i + 1] = r[i] + (n - 1 - i);
    }
    vector<i64> m(n + 1), bias(n + 1, 0);
    vector<i64> m_set;
    for(int i = 0; i <= n; ++i){
        m[i] = mod(x * i, d);
        bias[i] = body(x * i, d);
        m_set.emplace_back(m[i]);
    }
    i64 minbias = *min_element(bias.begin(), bias.end());
    for(auto& b : bias)
        b += minbias;
    sort(m_set.begin(), m_set.end());
    m_set.erase(unique(m_set.begin(), m_set.end()), m_set.end());

    vector<i64> m_sizes(m_set.size(), 2);
    for(int i = 0; i <= n; ++i){
        l[i] += bias[i];
        r[i] += bias[i] + 1;
        int idx = distance(m_set.begin(), lower_bound(m_set.begin(), m_set.end(), m[i]));
        chmax(m_sizes[idx], r[i]);
    }
    vector<Segtree<i64,i64>> seg;
    for(int i = 0; i < m_set.size(); ++i)
        seg.emplace_back(m_sizes[i], [](auto x, auto y){return x + y;}, [](auto x, auto y, i64 z){return max(y * z, x);}, [](auto x, auto y){return max(x, y);}, 0L, 0L);

    for(int i = 0; i <= n; ++i){
        int idx = distance(m_set.begin(), lower_bound(m_set.begin(), m_set.end(), m[i]));
        seg[idx].update(l[i], r[i], 1);
    }
    i64 ans = 0;
    for(int i = 0; i < m_set.size(); ++i){
        ans += seg[i].get(0, m_sizes[i]);
    }
    cout << (long long)(ans) << endl;


}


signed main()    assert(d >= 0);{
    long long N;
    scanf("%lld",&N);
    long long X;
    scanf("%lld",&X);
    long long D;
    scanf("%lld",&D);
    solve(N, X, D);
    return 0;
}


Compiler output:
In file included from /usr/include/c++/14/cassert:44,
                 from /usr/include/x86_64-linux-gnu/c++/14/bits/stdc++.h:106,
                 from a.cc:3:
a.cc:187:18: error: initializer provided for function
  187 | signed main()    assert(d >= 0);{
      |                  ^~~~~~
a.cc:187:33: error: expected unqualified-id before '{' token
  187 | signed main()    assert(d >= 0);{
      |                                 ^