题解 | #Counting Triangles#

Counting Triangles

https://ac.nowcoder.com/acm/contest/11254/J

n个点存在 cn3 即n(n-1)(n-2)/3! 个点
对于一个三边颜色不同的三角形存在两条颜色相同的边和一条颜色不同的边 既存在两个三角形角的两角边为异***r>故不满足条件的三角形个数=异色角个数/2; 满足条件的三角形个数便为 n(n-1)(n-2)/3!-异色角个数/2;
异色角的个数为对于两两点之间颜色为白的边与颜色为黑的边构成的角
O(n²) 求出每两点之间的异色边=黑色边*白色边(总边数n-1 - 黑色边)累加

include<bits/stdc++.h>

using namespace std;
#define ll long long
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;
bool edge[8005][8005];
int main()
{
int n, seed;
ll ans = 0;
cin >> n >> seed;
srand(seed);
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
edge[j][i] = edge[i][j] = read();
for (int i = 0; i < n; i++)
{
ll dg = 0;
for (int j = 0; j < n; j++)
if (edge[i][j])++dg;
ans += dg * (n - 1 - dg);
}
printf("%lld", (long long)n * (n - 1) * (n - 2) / 6 - ans / 2);
return 0;
}

全部评论
为什么j是0到n循环而不是i+1到n循环
点赞 回复 分享
发布于 2021-07-25 09:56

相关推荐

不愿透露姓名的神秘牛友
11-26 16:06
已编辑
快手电商 后端 23k-35k
点赞 评论 收藏
分享
offer多多的六边形战士很无语:看了你的博客,感觉挺不错的,可以把你的访问量和粉丝数在简历里提一下,闪光点(仅个人意见)
点赞 评论 收藏
分享
勤奋努力的椰子这就开摆:美团骑手在美团工作没毛病
投递美团等公司10个岗位
点赞 评论 收藏
分享
评论
11
1
分享
牛客网
牛客企业服务