这里提供另一种 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;
}
```