题解:AT_arc145_d [ARC145D] Non Arithmetic Progression Set
题意:很简单了,不再赘述。
做法:
一般来说,跟和/差有关的限制可以考虑进制之类的东西。
那么比较困难的是 \(y-x\not = z-y\) 这个限制,我们换为 \(x+z \not= 2y\)。
二进制的数要构造起来相当困难,我们考虑用三进制构造,我们取所有每一位是 0/1 的三进制数来构造就可以了,显然 \(2y\) 中都是 2,但是 \(x+z\) 不可能每一位都是 2,那么就满足了这个条件。
那么我们现在怎么构造和相等呢?
我们考虑我们所有数整体增加或减小是不会影响上面那个差的限制的,所以我们考虑先整体改再微调。
那么还会剩下一些,但是我们直接修会出问题,有的 1 会变成 2,这样就破坏了限制。
所以我们考虑所有数乘上 3,使得所有数最后一位都是 0,这样就不会破坏兴致了。
最后检验一下,极限情况都是符合限制的。
给出代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e4 + 5;
int n, m, id[maxn], pw[maxn];
signed main() {
cin >> n >> m;
pw[0] = 1;
for (int i = 1; i <= 20; i++)
pw[i] = pw[i - 1] * 3;
for (int i = 1; i <= n; i++) {
for (int j = 20; j >= 0; j--)
if((i >> j) & 1)
id[i] += pw[j];
id[i] = id[i] * 3;
}
int s = 0;
for (int i = 1; i <= n; i++)
s += id[i];
// cout << s << endl;
int t = (m - s) / n; s += n * t; m -= s;
if(m < 0) {
t--, m += n;
}
for (int i = 1; i <= n; i++)
id[i] += t;
for (int i = n - m + 1; i <= n; i++)
id[i]++;
for (int i = 1; i <= n; i++)
cout << id[i] << " ";
cout << endl;
return 0;
}

浙公网安备 33010602011771号