HDU4466 Triangle 计数 容斥原理

原文链接https://www.cnblogs.com/zhouzhendong/p/HDU4466.html

题目传送门 - HDU4466

题意

  多组数据,每次询问一个数 $n(nleq 5 imes 10^6)$ 。

  对于每一次询问,给出一根长度为n的铁丝。将其分成若干段并将每段折成一个三角形,使得三角形都相似。有多少种分法?

  其中,注意一下原题中的样例解释:同一个三角形里面的 3 条线段视为无序的,而划分出来的三角形视为有序的,即交换不同三角形的顺序算不同的方案。

  答案对 $10^9+7$ 取模。

题解

  我们首先考虑求把一根铁丝折成一个三角形的方案总数。

  下面这段文字摘自 https://www.cnblogs.com/jianglangcaijin/p/3465526.html

  设为 $f_M$ 周长为 $M$ 的三角形的个数。设三角形的三边 $a,b,c$ 满足 $aleq bleq c$ ,那么分两种情况:

  (1)$b=c$ ,此时 $c$ 的上限为 $cfrac{M-1}{2}$ ,下限为 $leftlceil cfrac M3 ight ceil=leftlfloorcfrac {M+2}{3} ight floor$ ,所以此时的三角形个数为 $leftlfloorcfrac{M-1}2 ight floor - leftlfloorcfrac{M+2}3 ight floor+1$ ;

  (2)$b eq c$ ,那么 $bleq c-1$ ,因为 $a+b>c>c-1$ ,因此一般来说有多少个三角形 $(a,b,c-1)$ 就有多少个三角形 $(a,b,c)$ ,但是此时要减去 $a+b=c$ 的情况。三角形 $(a,b,c-1)$ 的个数就是 $f_{M-1}$ 。此时若 $a+b=c$ ,即 $M-1=a+b+c-1=c+c-1$ ,即 $M=2c$ ,因此 $M$ 必须为偶数。$ a+b=c=leftlfloorcfrac M2 ight floor$ ,使得 $a+b=cfrac M2$ 的有序 $(aleq b)$ 二元组有 $leftlfloorcfrac M4 ight floor$ 。

  然后我们考虑如何处理出满足 $gcd(a,b,c)$ 的方案数。

  这个可以用类似素数筛法的方法,利用容斥原理处理。

  最后我们在回答询问的时候, $O(sqrt{n})$ 扫一下 $n$ 的所有因数然后统计一下答案就可以了。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=5e6+5,mod=1e9+7;
int Case=0,n,f[N],Pow[N];
int main(){
	Pow[0]=1;
	for (int i=1;i<N;i++){
		f[i]=(f[i-1]+(i-1)/2-i/3+mod)%mod;
		if (i%3==0)
			f[i]=(f[i]+1)%mod;
		if (i%2==0)
			f[i]=(f[i]-i/4+mod)%mod;
		Pow[i]=Pow[i-1]*2%mod;
	}
	for (int i=1;i<N;i++)
		for (int j=i*2;j<N;j+=i)
			f[j]=(f[j]-f[i]+mod)%mod;
	while (~scanf("%d",&n)){
		int ans=0;
		for (int i=1;i*i<=n;i++)
			if (n%i==0){
				ans=(1LL*f[i]*Pow[n/i-1]+ans)%mod;
				if (i*i!=n)
					ans=(1LL*f[n/i]*Pow[i-1]+ans)%mod;
			}
		printf("Case %d: %d
",++Case,ans);
	}
	return 0;
}

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU4466.html