原文链接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; }