Codeforces
CF Step
Youtube Linkedin Discord Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Code : Modular Sequence

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2 * (int)1e5 + 1;
const int inf = 1e6;
vector<int> dp, parent;

void precompute_dp() {
    dp.resize(maxn + 1, inf);
    parent.resize(maxn + 1, 0);

    // dp[i] is the minimum number of block elements required to make the
    // block sum equal to i.
    // No block is needed to create sum as 0.
    dp[0] = 0;
    parent[0] = -1;
    for (int i = 0; i < maxn; i++) {
        for (int cnt = 1; cnt < maxn; cnt++) {
            int sum = cnt * (cnt - 1) / 2;
            if (i + sum >= maxn) {
                break;
            }

            if (dp[i + sum] > cnt + dp[i]) {
                dp[i + sum] = cnt + dp[i];
                parent[i + sum] = i;
            }
        }
    }
}

vector<int> construct_blocks(int block_sum, int cnt) {
    vector<int> res;
    while (block_sum > 0) {
        int sum = block_sum - parent[block_sum];
        int curr = 0;
        for (int i = 0;; i++) {
            curr += i;
            res.push_back(i);
            if (curr == sum) {
                break;
            }
        }

        block_sum -= sum;
    }

    while (res.size() != cnt) {
        res.push_back(0);
    }
    return res;
}

void solve(int n, long long x, long long y, long long s) {
    // Try to do a split when the left half contains [0 ...i]
    // The right half contains the remaining suffix.
    for (int i = 0; i < n; i++) {
        long long lcnt, rcnt, lsum, rsum, block_sum;
        lcnt = i + 1;
        rcnt = n - lcnt;
        lsum = x * lcnt + y * (lcnt) * (lcnt - 1) / 2;
        rsum = s - lsum;

        block_sum = rsum - rcnt * (x % y);
        if (block_sum % y != 0) {
            continue;
        }
        block_sum /= y;
        if (block_sum >= 0 && dp[block_sum] <= rcnt) {
            cout << "YES" << endl;
            for (int j = 0; j < lcnt; j++) {
                cout << x + j * y << " ";
            }

            vector<int> blocks = construct_blocks(block_sum, rcnt);
            for (auto &ele : blocks) {
                ele = ele * y + (x % y);
                cout << ele << " ";
            }
            cout << endl;
            return;
        }
    }

    cout << "NO" << endl;
}

int main() {
    precompute_dp();

    int t;
    cin >> t;

    for (int i = 0; i < t; i++) {
        int n, x, y, s;
        cin >> n >> x >> y >> s;
        solve(n, x, y, s);
    }

    return 0;
}
#include <bits/stdc++.h>
using namespace std;

// Template Credits: CF114514ancestor
/******************** Template starts ****************************************/
#define int long long
#define _N 200005
int _z, _f[_N], _lstv[_N], _lstw[_N];
void construct_answer(int n, int x, int y, int s) {
    s -= (_z = x % y) * n, x /= y;
    _f[0] = 0;
    for (int j = 1; j <= s; j++)
        _f[j] = n + 2;
    for (int i = 1, v = 0, w = 0, j; i <= n; i++)
        for (v += (i - 1) * y, w = i, j = v; j <= s; j++)
            if (_f[j - v] + w < _f[j])
                _f[j] = _f[j - v] + w, _lstv[j] = v, _lstw[j] = w;
    for (int i = 1, v = 0; i <= n; i++) {
        v += (x + i - 1) * y;
        if (v <= s && _f[s - v] <= n - i) {
            for (int j = 1; j <= i; j++)
                cout << _z + (x + j - 1) * y << ' ';
            for (int j = 1; j <= n - i - _f[s - v]; j++)
                cout << _z << ' ';
            v = s - v;
            while (v) {
                for (int j = 1; j <= _lstw[v]; j++)
                    cout << _z + (j - 1) * y << ' ';
                v -= _lstv[v];
            }
            cout << '\n';
            return;
        }
    }
    cout << "You printed YES but no solution exists"
         << "\n";
}
#undef int
/******************** Template Ends ******************************************/

const int maxn = 2 * (int)1e5 + 1;
const int inf = 1e6;
vector<int> dp;

void precompute_dp() {
    dp.resize(maxn + 1, inf);

    // dp[i] is the minimum number of block elements required to make the
    // block sum equal to i.
    // No block is needed to create sum as 0.
    dp[0] = 0;
    for (int i = 0; i < maxn; i++) {
        for (int cnt = 1; cnt < maxn; cnt++) {
            int sum = cnt * (cnt - 1) / 2;
            if (i + sum >= maxn) {
                break;
            }
            dp[i + sum] = min(dp[i + sum], cnt + dp[i]);
        }
    }
}

bool solve(int n, long long x, long long y, long long s) {
    // Try to do a split when the left half contains [0 ...i]
    // The right half contains the remaining suffix.
    for (int i = 0; i < n; i++) {
        long long lcnt, rcnt, lsum, rsum, block_sum;
        lcnt = i + 1;
        rcnt = n - lcnt;
        lsum = x * lcnt + y * (lcnt) * (lcnt - 1) / 2;
        rsum = s - lsum;

        block_sum = rsum - rcnt * (x % y);
        if (block_sum % y != 0) {
            continue;
        }
        block_sum /= y;
        if (block_sum >= 0 && dp[block_sum] <= rcnt) {
            return true;
        }
    }
    return false;
}

int main() {
    precompute_dp();

    int t;
    cin >> t;

    for (int i = 0; i < t; i++) {
        int n, x, y, s;
        cin >> n >> x >> y >> s;
        if (solve(n, x, y, s)) {
            cout << "YES" << endl;
            construct_answer(n, x, y, s);
        } else {
            cout << "NO" << endl;
        }
    }

    return 0;
}