1. 程式人生 > >HDU 4466 Triangle

HDU 4466 Triangle

col rod ren rip ons help 多少 have this

Triangle

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)

Problem Description

You have a piece of iron wire with length of n unit. Now you decide to cut it into several ordered pieces and fold each piece into a triangle satisfying:
*All triangles are integral.
* All triangles are pairwise similar.
You should count the number of different approaches to form triangles. Two approaches are considered different if either of the following conditions is satisfied:
*They produce different numbers of triangles.
* There exists i that the ith

(again, pieces are ordered) triangle in one approaches is not congruent to ith triangle in another plan.
The following information can be helpful in understanding this problem.
* A triangle is integral when all sides are integer.
*Two triangles are congruent when all corresponding sides and interior angles are equal.
* Two triangles are similar if they have the same shape, but can be different sizes.
*For n = 9 you have 6 different approaches to do so, namely
(1, 1, 1) (1, 1, 1) (1, 1, 1)
(1, 1, 1) (2, 2, 2)
(2, 2, 2) (1, 1, 1)
(1, 4, 4)
(2, 3, 4)
(3, 3, 3)
where (a, b, c) represents a triangle with three sides a, b, c.

Input

There are several test cases.
For each test case there is a single line containing one integer n (1 ≤ n ≤ 5 * 106).
Input is terminated by EOF.

Output

For each test case, output one line “Case X: Y” where X is the test case number (starting from 1) and Y is the number of approaches, moduled by 109 + 7.

Sample Input

1 2 3 4 5 6 8 9 10 11 12 15 19 20 100 1000

Sample Output

Case 1: 0 Case 2: 0 Case 3: 1 Case 4: 0 Case 5: 1 Case 6: 2 Case 7: 1 Case 8: 6 Case 9: 3 Case 10: 4 Case 11: 10 Case 12: 25 Case 13: 10 Case 14: 16 Case 15: 525236 Case 16: 523080925

題意

長度為的鐵絲,你可以將其分成若幹段,並把每段都折成一個三角形。你還需要保證三角形的邊長都是正整數並且三角形兩兩相似,問有多少種不同的分法。

題解

設w[i]為長度為i的鐵絲的分法,一種分法的所有三角形邊長除以gcd(a,b,c)得到的三角形都一樣,且三邊互質,設邊長為a’,b’,c’。

若M=a+b+c,M’=a’+b’+c’,設k=M/M’,那麽以a’,b’,c’為三邊的三角形為基,用長度為M的鐵絲能做出的方案數為2^(k-1)。

設g[i]為長度為i的鐵絲分成邊長為a,b,c(a<=b<=c)且gcd(a,b,c)=1的三角形的方案數。

那麽w[i]=g[p1]*2^(i/p1-1)+g[p2]*2^(i/p2-1)+…+g[pk]*2^(i/pk-1)(p為i的因數且p>=3)。

例:w[12]=g[12]*1+g[6]*2+g[4]*4+g[3]*8。

設f[i]為長度為i的鐵絲分成邊長為a,b,c(a<=b<=c)的三角形的方案數。

那麽g[i]=f[i]-f[p1]-f[p2]-…-f[pk](p為i的因數且p>=3)。

例:g[12]=f[12]-f[6]-f[4]-f[3]。

考慮如何求f[i]。

分兩種情況:

1.b==c,c最小為ceil(i/3),最大為floor((i-1)/2) 。

2.b<c,那麽就是求a<=b<=c-1的方案數,為f[i-1]。

第二種情況還要除去a+b=c的方案數。

若a+b=c,那麽i=a+b+c=2*(a+b),a+b=i/2,這樣的(a,b)有i/2/2對,此時i一定為偶數,所以i為偶數時要考慮這種情況。

代碼

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=5000005,mod=1000000007;
int n,ans,cnt;
int f[N],p[N];
int main(){
	p[1]=1;
	for(int i=2;i<=N;i++)p[i]=(p[i-1]*2)%mod;
	f[3]=1;
	for(int i=4;i<=N;i++){
		f[i]=f[i-1]+(i-1)/2-i/3+(i%3?0:1);
		if(i%2==0)f[i]-=i/4;
		f[i]%=mod;
		if(f[i]<0)f[i]+=mod;
	}		
	for(int i=2;i<=N;i++)
		for(int j=2;i*j<=N;j++){
			f[i*j]-=f[i];
			if(f[i*j]<0)f[i*j]+=mod;
		}
	while(~scanf("%d",&n)){
		ans=0;
		for(int i=1;i*i<=n;i++){
			if(n%i!=0)continue;
			ans=(ans+1ll*f[i]*p[n/i])%mod;
			if(i*i!=n)ans=(ans+1ll*f[n/i]*p[i])%mod;	
		}
		printf("Case %d: %d\n",++cnt,ans);		
	}
	return 0;
}

HDU 4466 Triangle