题目大意:
给定一个无向完全图,求其中边颜色相同的三角形有多少个。
思路:
赛时写了一个自以为 O ( O( O(n^2 ) ) ) 的搜索(实则 O ( O( O(n^3 ) ) ))😥。
其实可以根据高中知识得出三角形的个数为 n ∗ ( n − 1 ) ∗ ( n − 2 ) / 6 n*(n-1)*(n-2)/6 n∗(n−1)∗(n−2)/6,如果三角形不满足三条边颜色相同的话,那肯定有两条边颜色相同,所以我们只需要遍历每一个点,记录其黑边与白边的乘积也就是不合格的三角形个数的二倍,最后用总数减去他的二分之一即可。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<sstream>
#include<queue>
#define pi 3.1415926535
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
typedef pair<int, int> pii;
const int N = 1e6 + 10;
namespace GenHelper
{
unsigned z1, z2, z3, z4, b, u;
unsigned get()
{
b = ((z1 << 6) ^ z1) >> 13;
z1 = ((z1 & 4294967294U) << 18) ^ b;
b = ((z2 << 2) ^ z2) >> 27;
z2 = ((z2 & 4294967288U) << 2) ^ b;
b = ((z3 << 13) ^ z3) >> 21;
z3 = ((z3 & 4294967280U) << 7) ^ b;
b = ((z4 << 3) ^ z4) >> 12;
z4 = ((z4 & 4294967168U) << 13) ^ b;
return (z1 ^ z2 ^ z3 ^ z4);
}
bool read() {
while (!u) u = get();
bool res = u & 1;
u >>= 1; return res;
}
void srand(int x)
{
z1 = x;
z2 = (~x) ^ 0x233333333U;
z3 = x ^ 0x1234598766U;
z4 = (~x) + 51;
u = 0;
}
}
using namespace GenHelper;
int n, seed;
bool edge[8005][8005];
void inint(){
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
edge[j][i] = edge[i][j] = read();
}
int main() {
cin >> n >> seed;
srand(seed);
inint();
ll cnt = 0;
int n1,n2;
for (int i = 0; i < n; i++) {
n1=n2=0;
for (int j = 0; j < n; j++) {
if(i==j)continue;
if (edge[i][j]) n1++;
else n2++;
}
cnt+=n1*n2;
}
ll res = (ll) n*(ll)(n-1)*(ll)(n-2)/6;
cout << res-cnt/2 << endl;
return 0;
}