#include using namespace std; typedef long long LL; const int N = 15010, M = 40010; int n, m; // 魔法值的上限是n,个数是m int x[M]; // 原始的魔法值 LL cnt[N]; // 每个魔法值计数用的桶 LL num[N][4]; // 以某个魔法值i为a,b,c,d时的个数,记录在num[i][0],num[i][1],num[i][2],num[i][3]中,也就是答案 // 85分 3层循环,按桶的思路枚举每个魔法值,暴力枚举a,b,c,然后利用数学办法计算出d // 17/20 85分 // 快读 LL read() { LL x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar(); } return x * f; } int main() { #ifndef ONLINE_JUDGE freopen("468.in", "r", stdin); #endif n = read(), m = read(); for (int i = 1; i <= m; i++) { x[i] = read(); cnt[x[i]]++; // 记录每个魔法值的个数 } // 不再枚举每个输入的顺序,而是枚举每个魔法值,原因是魔法值的上限是固定的n for (int a = 1; a <= n; a++) // 枚举每个魔法值,上限是n for (int b = a + 1; b <= n; b++) for (int c = b + 1; c <= n; c++) { if ((b - a) & 1 || 3 * (b - a) >= (c - b)) continue; // 把已知条件反着写,符合这样要求的,直接continue掉 int d = b - a + c * 2 >> 1; // d可以通过数学办法计算获得 // 这里有一个数学的小技巧,就是先求总的个数,再除掉自己的个数 // 现在枚举到的每个(a,b,c,d)组合都是一种合法的组合,同时,由于每个数值不止一个,根据乘法原理,需要累乘个数才是答案 LL ans = cnt[a] * cnt[b] * cnt[c] * cnt[d]; // if (ans) cout << a << " " << b << " " << c << " " << d << endl; num[a][0] += ans; num[b][1] += ans; num[c][2] += ans; num[d][3] += ans; } for (int i = 1; i <= n; i++) for (int j = 0; j < 4; j++) num[i][j] /= cnt[i] ? cnt[i] : 1; for (int i = 1; i <= m; i++) { // 枚举每个序号 for (int j = 0; j < 4; j++) // 此序号作为a,b,c,d分别出现了多少次 // 举栗子:i=2,x[i]=5,也就是问你:5这个数,分别做为a,b,c,d出现了多少次? printf("%lld ", num[x[i]][j]); puts(""); } return 0; }