CSUST 4007-你真的会图论吗?(思维-三元环)

题目链接:http://acm.csust.edu.cn/problem/4007
博客园食用链接:https://www.cnblogs.com/lonely-wind-/p/13439655.html

Description

给你一张完全无向图,每条边有两种颜色(黑色或者白色),你需要求出有多少个三元环,路径上边的颜色相同给你一张完全无向图,每条边有两种颜色(黑色或者白色),你需要求出有多少个三元环,路径上边的颜色相同

Input
第一行一个正整数 n n n,表示这张完全图的点数. ( 1 ≤ n ≤ 5 e 3 ) (1 \leq n \leq 5e3) (1n5e3)

第二行五个整数, A , B , C , P , D , 1 ≤ A , B , C , P , D ≤ 1 0 9 A,B,C,P,D,1 \leq A,B,C,P,D \leq 10^9 A,B,C,P,D,1A,B,C,P,D109
,且 D ≤ P D \leq P DP,然后我们规定,对于边 i , j ( i < j ) i,j(i \lt j) i,j(i<j),如果 ( A ( i + j ) 2 + B ( i − j ) 2 + C ) m o d    P > D (A(i+j)^2 + B(i-j)^2 +C) \mod P>D (A(i+j)2+B(ij)2+C)modP>D,则该边为黑色,否则为白色.

Output
输出一个数表示结果

Sample Input 1
6
2 3 4 11 5
Sample Output 1
6

正所谓正难则反,对于直接选出同色的三元环可能会不知道怎么入手,那么我们考虑将所有的三元环减去不符合条件的三元环。那么总共的三元环个数很好算,就是 C n 3 C_n^3 Cn3,对于不符合条件的三元环,我们知道他们一定会有两条边颜色相异,而这两条边一定是由某个点延伸出去的,那么我们直接枚举这个点,然后再枚举他的边就好了(也就是枚举其他所有的点)

接下来的关键就是如何在一个点的所有边中计算不合法的三元环了。为了不重复,我们对该点延伸的每个边找在他前面的和他颜色互异的边,然后直接加上就好了。但所需要考虑的是重复的问题,虽然对于点内的三元环来讲没有重复了,但对于点之间的三元环就可能会出现重复了,比如说对于如下三元环而言:
在这里插入图片描述
2到5到6是相异的,但一定会有一个点,假设是5使得5-6,5-2同色,也一定会有一个点假设是6使得6-5,6-2异色。那么也就是一个不合法的三元环一定会重复2次计算。

那么代码也就出来了。
以下是AC代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mac=5e3+10;

bool color[mac][mac];//0为白色,1为黑色

ll pw(int x) {return 1LL*x*x;}

int main(int argc, char const *argv[])
{
	int n;
	scanf ("%d",&n);
	int a,b,c,d,p;
	scanf ("%d%d%d%d%d",&a,&b,&c,&p,&d);
	for (int i=1; i<=n; i++){
		for (int j=i+1; j<=n; j++){
			ll val=(1LL*a*pw(i+j)+1LL*b*pw(i-j)+c)%p;
			if (val>d) {color[i][j]=color[j][i]=true;}
			else {color[i][j]=color[j][i]=false; }
		}
	}
	ll ans=1LL*n*(n-1)*(n-2)/6;
	ll res=0;
	for (int i=1; i<=n; i++){
		int black=0,white=0;
		for (int j=1; j<=n; j++){
			if (i==j) continue;
			if (color[i][j]) {res+=white; black++;}
			else {res+=black; white++;}
		}
	}
	ans-=res/2;
	printf("%lld\n",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值