2023“钉耙编程”联赛 Day 2 G 题 - foreverlasting and fried-chicken 题解

原题题目

题面经过我校选手感性+理性+恶搞翻译。

众所周知,在北京理工大学有两位ACM英雄分别被称为 foreverlasting \text{foreverlasting} foreverlasting fried-chicken \text{fried-chicken} fried-chicken

他们分别沉浸在完美的爱情中。以下链接讲述了 fried-chicken \text{fried-chicken} fried-chicken 的爱情故事。

This

DuangDuck \text {DuangDuck} DuangDuck 喜欢图论和数学,他需要你的帮助解决一个简单的问题。

给定一个简单无向图命名为 fried-chicken \text{fried-chicken} fried-chicken,其中有 n n n 个节点和 m m m 条边。请注意,该图不一定是连通的。节点从 1 1 1 n n n 进行标号。

DuangDuck \text {DuangDuck} DuangDuck 想知道在 fried-chicken \text{fried-chicken} fried-chicken 图中有多少个 foreverlasting \text{foreverlasting} foreverlasting 图。

以上图像定义了一个 foreverlasting \text{foreverlasting} foreverlasting 图。

请注意,当两个 foreverlasting \text{foreverlasting} foreverlasting 图的边集之间至少有一条不同的边时,这两个图被认为是不同的。

换句话说,给定的图 G ( V , E ) G(V,E) G(V,E)。你需要计算满足 V ′ = { v 1 , v 2 , v 3 , v 4 , v 5 , v 6 , v 7 , v 8 } , E ′ = { ( v 1 , v 3 ) , ( v 2 , v 3 ) , ( v 3 , v 4 ) , ( v 3 , v 5 ) , ( v 3 , v 6 ) , ( v 3 , v 7 ) , ( v 4 , v 8 ) , ( v 5 , v 8 ) , ( v 6 , v 8 ) , ( v 7 , v 8 ) } V′=\{v_1,v_2,v_3,v_4,v_5,v_6,v_7,v_8\},E′=\{(v_1,v_3),(v_2,v_3),(v_3,v_4),(v_3,v_5),(v_3,v_6),(v_3,v_7),(v_4,v_8),(v_5,v_8),(v_6,v_8),(v_7,v_8)\} V={v1,v2,v3,v4,v5,v6,v7,v8},E={(v1,v3),(v2,v3),(v3,v4),(v3,v5),(v3,v6),(v3,v7),(v4,v8),(v5,v8),(v6,v8),(v7,v8)} 的子图 G ′ ( V ′ , E ′ ) G′(V′,E′) G(V,E) 的数量。

由于答案可能非常大, DuangDuck \text {DuangDuck} DuangDuck 想知道答案对 1 0 9 + 7 10^9+7 109+7 取模的结果。

样例

输入样例

1
8 10
1 2
1 3
1 4
1 5
1 6
1 7
8 4
8 5
8 6
8 7

输出样例

1

题目解析

考虑暴力枚举,显然会时超,可以考虑枚举比较关键的点。

我们发现中间四个点链接的两个点比较好枚举,我们枚举这两个点,为 ( i , j ) (i,j) (i,j),在两者都连接的点 x x x 的集合 X X X 中选择四个作为中间点,方案为 C size X 4 C_{\text {size}_X}^4 CsizeX4

同理我们再在 i i i 连接的点 y y y 的集合 Y Y Y 中选择两个作为上面的点,方案为 C size Y − 4 2 C_{\text {size}_Y-4}^2 CsizeY42

显然这里的减四是因为前面已经从 Y Y Y 的子集 X X X 中选择了四个点。

注意特判 j ∈ Y j\in Y jY 的情况,此时 Y Y Y 集合不可以选择 j j j,否则形状是不对的,因此需要减 5 5 5

两者相乘即可。

时间复杂度为 O ( n 3 64 ) O(\dfrac{n^3}{64}) O(64n3),足够通过本题。

注意需要适当卡常,以下代码常数可能比较大。

代码实现

#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL N=1005;
const LL mod=1e9+7;
LL T,n,m,x,y;
bitset<N>a[N];
LL C(LL x,LL y)
{
	if(x<y)return 0;
	if(y==2)return (x*(x-1)/2)%mod;
	return (x*(x-1)*(x-2)*(x-3)/24)%mod;
}
int main()
{
	scanf("%lld",&T);
	while(T--)
	{
		for(int i=1;i<=n;i++)a[i]=a[0];
		scanf("%lld%lld",&n,&m);
		for(int i=1;i<=m;i++)
		{
			scanf("%lld%lld",&x,&y);
			a[x][y]=1,a[y][x]=1;
		}
		LL ans=0;
		for(int i=1;i<=n;i++)
		{
			LL k=a[i].count();
			for(int j=1;j<=n;j++)
			{
				if(i==j)continue;
				bitset<N>tmp=a[i]&a[j];
				if(a[i][j]==1)ans+=C(tmp.count(),4)*C(k-5,2)%mod;
				else ans+=C(tmp.count(),4)*C(k-4,2)%mod;
				ans%=mod;
			}
		}
		printf("%lld\n",ans);
	}	
	
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值