题解 CF229C Triangles
对于一个完全图,三角形的个数显然是
现在把一些边挪到了另一个平面,那么就会有一些原本存在的三角形被拆掉了
我们选择把在原平面上的边染成红色,另一个平面上的边染成蓝色
这样就可以把两个平面变成一个了
样例大概长这样
那么我们要求的就是 三边全红 或者 三边全蓝 的三角形
直接数不好数,选择用 所有三角形的数量 - 不合法的三角形数量
那么问题就变成了求 不合法的三角形数量
显然不合法的三角形满足 两红一蓝 或者 一红两蓝
上面两个条件等价于 三条边中至少有一条红边和一条蓝边
考虑一个点
由于每一条从
(由于一红一蓝已经满足了条件,我们并不需要去考虑第三条边的颜色)
所以这个点贡献的不合法三角形个数为
但是这么算会有重复
拿样例来说,对于三角形
点
因为 两红一蓝 或者 一红两蓝 的三角形中有且只有一个点的两条边都是同色的
所以只有两个点有贡献,一个三角形会被重复算两次
所以
然后你就会发现
但因为是完全图,所以
所以
只需要统计
复杂度
#include<iostream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int N=1005000;
int n,m;
int b[N];
long long ans;
inline long long read(){
long long re=0,k=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') k=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
re=re*10+ch-'0';
ch=getchar();
}
return re*k;
}
int main(){
n=read(),m=read();
for(int i=1;i<=m;i++){
int x=read(),y=read();
b[x]++,b[y]++;
}
for(int i=1;i<=n;i++) ans-=(long long)b[i]*(n-1-b[i]);
ans=ans/2+(long long)(n-2)*(n-1)*n/6;
printf("%lld\n",ans);
return 0;
}