题意解析
我们使用 AiA_iAi 的二进制位来表示 iii 和其他点之间是否有边。
为了方便运算,我们可以只存储编号较小的点到编号较大点的边。
当 iii 和 jjj 固定不变时,满足条件的 kkk 的个数即 Ai,k=Aj,k=1A_{i,k}=A_{j,k}=1Ai,k =Aj,k =1 的个数,即 Ai AND AjA_i\ \mathrm{AND}\ A_jAi AND Aj 中 111 的个数。
因此,我们可以使用 std::bitset 来实现
A1,A2,…,ANA_1,A_2,\dots,A_NA1 ,A2 ,…,AN 并枚举 (i,j)(i,j)(i,j) 计算 Ai AND AjA_i\ \mathrm{AND}\ A_jAi AND Aj 中的 111 个数,总共需要 O(Nw)O(\frac{N}{w})O(wN ) 时间其中 w=64w = 64w=64,因此总的时间复杂度为 O(N3w)\mathrm{O}(\frac{N^3}{w})O(wN3 )。
由于 3000364=421875000≃4×108\frac{3000^3}{64}=421875000 \simeq 4 \times 10^86430003 =421875000≃4×108 ,这个解法已经足够快了。我们只需枚举 i,j(i<j)i,j(i < j)i,j(i<j) 就能进一步将执行时间减半。
AC代码