这个题也不是很难,就是个一般的三元环计数
今天用一种奇怪的做法 bitset b i t s e t 来优化
bitset b i t s e t 是个很好用的东西 类似于一个二进制数 但是时间和空间消耗都很小
它大概有以下操作
1. 1. 所有的位运算,例如 <<,>>,|,⊕ << , >> , | , ⊕ 还有&运算
2. 2. 一些相关的函数
#include<iostream>
#include<bitset>
std::bitset<233> f;
int main() {
f.size(); //bitset的大小 在这里就是233
f.count(); //bitset 中二进制1的个数
f.set(); //所有位都设为1
f.reset(); //所有的位都设为0
f.set(u); //把第u位设为1
f.reset(u); //把第u位设为0
f.any(); //是否存在一位是1
f[x]; // 访问第x位的元素
f.flip(); //取反所有位
f.flip(x); //取反第x位
f.to_ulong(); //转化为unsigned long 并返回
}
反正这个东西自带一个 1ω 1 ω 的常数,可以优化一些过不了的东西
64 64 位的机器上 ω=64 ω = 64 这样子 n3 n 3 的算法就可以优化到 O(n3ω) O ( n 3 ω ) 就能跑 n=1000 n = 1000 了
这个题加上 bitset b i t s e t 的做法之后就可以直接跑最暴力的做法了
首先把每个点的出边和入边都用 bitset b i t s e t 存下来
然后暴力枚举两个点, a−>b a − > b , 把 a a 的入边和的出边进行与操作后里面 1 1 的个数加入答案就够了。
因为三元环每条边都被枚举到了一次 最后答案除个3就好了
记得开
复杂度 O(n3ω) O ( n 3 ω )
Codes
#include<bits/stdc++.h>
using namespace std;
const int N = 1500 + 10;
bitset<N> in[N], out[N];
int a[N][N], ans;
int main() {
freopen("triatrip.in", "r", stdin);
freopen("triatrip.out", "w", stdout);
int n; long long ans = 0; char c;
scanf("%d", &n);
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j) {
cin >> c;
if(c == '+') {
a[i][j] = 1;
out[i][j] = 1;
in[j][i] = 1;
}
}
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j)
if(a[i][j])
ans += (out[j] & in[i]).count();
cout << ans / 3 << endl;
return 0;
}