L. Coordinate Paper
构造一个长度为 n n n的序列 a a a,满足 a i ≥ 0 a_i \geq 0 ai≥0, ∑ i = 1 n a i = s \sum\limits_{i = 1} ^{n} a_i = s i=1∑nai=s,对于任意的 i ∈ [ 1 , n − 1 ] i \in [1, n - 1] i∈[1,n−1],都有 a i − a i + 1 = k o r a i + 1 − a i = 1 a_i - a_{i + 1} = k\ or\ a_{i + 1} - a{i} = 1 ai−ai+1=k or ai+1−ai=1,其中 n , s , k n, s, k n,s,k是给定的数。
假定所有的 a i a_i ai都满足 a i + 1 − a i = 1 a_{i + 1} - a_{i} = 1 ai+1−ai=1,则对于一个给定的 a 1 a_1 a1,有 ∑ i = 1 n a i = n × a 1 + n ( n − 1 ) 2 \sum\limits_{i = 1} ^{n} a_i = n \times a_1 + \frac{n(n - 1)}2 i=1∑nai=n×a1+2n(n−1),考虑 a i − a i + 1 = k a_i - a_{i + 1} = k ai−ai+1=k, ∑ i = 1 n a i = n × a 1 + n ( n − 1 ) 2 − x ( k + 1 ) \sum\limits_{i = 1} ^{n} a_i = n \times a_1 + \frac{n(n - 1)}2- x (k + 1) i=1∑nai=n×a1+2n(n−1)−x(k+1)。
考虑对所有数 ( m o d k + 1 ) \pmod {k + 1} (modk+1)下找到一个解,满足 ∑ i = 1 n a i ( m o d k + 1 ) ≡ s ( m o d k + 1 ) \sum\limits_{i = 1} ^{n} a_i \pmod {k + 1} \equiv s \pmod {k + 1} i=1∑nai(modk+1)≡s(modk+1)。
考虑同余下的一个最小解, a 1 , a 1 + 1 , … , k , 0 , 1 , 2 , … , k , 0 , 1 , 2 , … a_1, a_1 + 1, \dots, k, 0, 1, 2, \dots, k, 0, 1, 2, \dots a1,a1+1,…,k,0,1,2,…,k,0,1,2,…,如果满足 s u m ≤ s a n d s u m ( m o d k + 1 ) ≡ s ( m o d k + 1 ) sum \leq s \ and\ sum \pmod{k + 1} \equiv s \pmod{k + 1} sum≤s and sum(modk+1)≡s(modk+1),则说明找到一组解。
获得最小解后,凑得答案,只需每次对最小得加 k + 1 k + 1 k+1,这样可以保证变动之后这个数比其前方的大 1 1 1,后面的比其小 k k k,满足要求。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, k, flag;
long long s, a[N];
vector<int> pos[N];
inline int add(int x, int y) {
return x + y < k + 1 ? x + y : x + y - k - 1;
}
void solve() {
for (int i = 1; i <= n; i++) {
a[i] = add(a[i - 1], i != 1);
pos[a[i]].push_back(i);
}
int x = a[1], len = min(k - x + 1, n), last = n - len;
long long sum = 1ll * (x + x + len - 1) * len / 2;
sum += 1ll * (last / (k + 1)) * (0 + k) * (k + 1) / 2;
last %= k + 1;
sum += 1ll * (0 + 0 + last - 1) * last / 2;
s -= sum;
sum = s / (k + 1);
long long tot = sum / n, more = sum % n;
for (int i = 1; i <= n; i++) {
a[i] += 1ll * (k + 1) * tot;
}
for (int i = 0; i <= k; i++) {
for (auto it : pos[i]) {
if (more) {
a[it] += k + 1;
more--;
}
}
}
for (int i = 1; i <= n; i++) {
printf("%lld%c", a[i], i == n ? '\n' : ' ');
}
}
bool judge(int x) {
int len = min(k - x + 1, n), last = n - len;
long long sum = 1ll * (x + x + len - 1) * len / 2;
sum += 1ll * (last / (k + 1)) * (0 + k) * (k + 1) / 2;
last %= k + 1;
sum += 1ll * (0 + 0 + last - 1) * last / 2;
return sum <= s && s % (k + 1) == sum % (k + 1);
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
cin >> n >> k >> s;
for (int i = 0; i <= k; i++) {
if (judge(i)) {
flag = 1;
a[0] = i;
solve();
break;
}
}
if (!flag) {
puts("-1");
}
return 0;
}