题目信息
解题思路
在此图中,A表示xa,B表示xb,C表示xc,D表示xd,那么这四个点就能组成一个魔法阵。
令k = xd - xc。
根据题目条件可得:
- xb - xa = 2k
- xc - xb > 6k
综上,可求出:
1 ≤ k ≤ n / 9
所以我们可以枚举k和d的位置,这样就可以确定C和D的值了。
定义sumi为第i中方案数(算完了记录后马上改变),那么:
- sumd = suma * sumb * sumc
- sumc = suma * sumb * sumd
同理,我们继续枚举a的位置,确定A和B的值,可得:
- suma = sumb * sumc * sumd
- sumb = suma * sumc * sumd
对于每一个xi,我们输出对应的az[i], bz[i], cz[i]和dz[i]即可。
时间复杂度:O(n2),即O((n / 9) 2)
代码实现
#include <bits/stdc++.h>
using namespace std;
const int N = 40005, M = 15005;
int x[N], z[N][5], sum[M];
int main() {
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; ++i) {
cin >> x[i];
++sum[x[i]];
}
for (int k = 1; k * 9 < n; ++k) {
int pre = 0;
int a, b, c, d;
// 枚举d
for (d = k * 9 + 2; d <= n; ++d) {
a = d - 9 * k - 1;
b = d - 7 * k - 1;
c = d - k;
// 前缀和
pre += sum[b] * sum[a];
z[c][3] += sum[d] * pre;
z[d][4] += sum[c] * pre;
}
pre = 0;
// 枚举a
for (a = n - k * 9 - 1; a >= 1; --a) {
b = a + 2 * k;
c = a + k * 8 + 1;
d = a + k * 9 + 1;
pre += sum[c] * sum[d];
z[a][1] += sum[b] * pre;
z[b][2] += sum[a] * pre;
}
}
for (int i = 1; i <= m; ++i) {
cout << z[x[i]][1] << ' ' << z[x[i]][2] << ' ' << z[x[i]][3] << ' ' << z[x[i]][4] << '\n';
}
return 0;
}