P5123 题解

Tarantula

2022-01-24 13:29:19

Solution

这里提供另一种 bitset 的做法。 首先对于每一个冰淇淋 ID 都开一个 bitset 是不现实的,因为 ID 可能会到 $10^6$,空间直接上天。 考虑把所有的 ID 离散化,再去重,这样 ID 的种数大大减少。但是空间还是会爆,还需要继续优化。 我们发现如果某个 ID 只出现过一次,那么我们可以直接把这个 ID 扔掉。因为拥有这个 ID 的奶牛绝对不可能依靠它去与别的奶牛和谐共处。 因此只需要考虑出现次数大于等于 $2$ 的所有 ID 了。 这样的话空间复杂度相当玄学,但事实证明空间开销其实相当小,只有 $7.25$ 个 MB。 时间复杂度 $O(\frac{n^2}{32})$。 ```cpp #include<bits/stdc++.h> using namespace std; int n; vector<bitset<50005> > a; bitset<50005> tmp; int x[50005][6]; bool p[50005][6]; int sum[1000005]; int ind[250005], cnt; long long ans; inline int read() { int x = 0; char c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)) {x = (x << 3) + (x << 1) + (c ^ 48); c = getchar();} return x; } int main() { freopen("cowpatibility.in", "r", stdin); freopen("cowpatibility.out", "w", stdout); n = read(); for (int i = 1; i <= n; ++i) for (int j = 1; j <= 5; ++j) sum[x[i][j] = read()]++; for (int i = 1; i <= n; ++i) for (int j = 1; j <= 5; ++j) if (sum[x[i][j]] > 1) ind[++cnt] = x[i][j], p[i][j] = 1; sort(ind + 1, ind + 1 + cnt); int m = unique(ind + 1, ind + 1 + cnt) - ind - 1; a.resize(m + 1); for (int i = 1; i <= n; ++i) for (int j = 1; j <= 5; ++j) if (p[i][j]) x[i][j] = lower_bound(ind + 1, ind + 1 + m, x[i][j]) - ind; for (int i = 1; i <= n; ++i) { tmp.reset(); for (int j = 1; j <= 5; ++j) if (p[i][j]) {tmp |= a[x[i][j]]; a[x[i][j]].set(i - 1);} ans += (int)tmp.count(); } printf("%lld\n", 1ll * n * (n - 1) / 2 - ans); return 0; } ```