Files
python/TangDou/CSP-J/AcWingTraining/T6/468_BruteForce_3.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

65 lines
2.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
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;
}