糖果
CallMeCad某天买了非常多的糖果并把它们分成N份,依次分别有1,2,3…,N个糖果。他想拿出其中的3份分给他的室友, 为了不让室友们闹意见,必须让这三份的糖果总数恰好能被三人均分。请问他一共有多少种不同的组合方案数?
输入
有多组输入数据,每组输入非负整数N(3≤N≤106)。
输出
每组数据输出一个整数独占一行,表示共有多少种方案,由于可能会很大,最后结果对10^9+7取模。
样例输入
3
4
5
样例输出
1
2
4
一.题目分析
- 先将n分成三类:3的倍数, 3的倍数余1, 3的倍数余2
- 再考虑取出的三份糖果的来源可能有哪几种情况
- 将n个糖果分成3类:x={3的倍数}, y={3的倍数余1}, z={3的倍数余2}
- 一共有4种情况:
- 取于x,x,x
- 取于y,y,y
- 取于z,z,z
- 取于x,y,z
- 然后分别对这几种情况进行计算
- 最后不要忘记取模
二.AC代码
#include<stdio.h>
#include<math.h>
long long int f(long long int x);
int main()
{
long long int n,ans,mod=1000000007;
while(~scanf("%lld",&n))
{
if(n%3==0)
{
ans=(n*n*n)/27;//注意此处不能用(long long )pow(n/3,3),否则就会一直wrong answer,用后面那个999999这个数据不一样
ans=(ans+3*f(n/3));
}
else if(n%3==1)
{
ans=((n-1)/3)*((n-1)/3)*(((n-1)/3)+1);
ans=(ans+2*f((n-1)/3)+f(((n-1)/3)+1));
}
else if(n%3==2)
{
ans=((n-2)/3)*(((n-2)/3)+1)*(((n-2)/3)+1);
ans=(ans+2*f(((n-2)/3)+1)+f((n-2)/3));
}
printf("%lld\n",ans%mod);
}
return 0;
}
long long int f(long long int x)
{
if(x<3) return 0;
long long int y=1;
for(long long int i=x;i>x-3;i--)
{
y=(y*i);
}
y/=6;
return y;
}