描述
L国是一个有着优美景色且物产丰富的国家,很多人都喜欢来这里旅游并且喜欢带走一些纪念品,大神同学也不例外。距离开L国的时间越来越近了,大神同学正在烦恼给她可爱的小伙伴们带什么纪念品好,现在摆在大神同学面前的有三类纪念品A, B, C可以选择,每类纪念品各有N种。其中种类为A_i, B_i, C_i的纪念品价值均为i, 且分别有N+1-i个剩余。现在大神同学希望在三类纪念品中各挑选一件然后赠送给她的三名可爱的小伙伴,但是她又不希望恰好挑出来两件价值相同的纪念品,因为这样拿到相同价值纪念品的两位小伙伴就会认为大神同学偏袒另一位小伙伴而不理睬她超过一星期。现在,大神同学希望你买到的三件纪念品能让三位小伙伴都开心并且不和她闹别扭,她想知道一共有多少种不同挑选的方法?
因为方案数可能非常大,大神同学希望知道挑选纪念品的方案数模10^9+7之后的答案。
输入
第一行包括一个数T,表示数据的组数。
接下来包含T组数据,每组数据一行,包括一个整数N。
输出
对于每组数据,输出一行“Case x: ”,其中x表示每组数据的编号(从1开始),后接一个数,表示模10^9+7后的选择纪念品的方案数。
数据范围
小数据:
1<=T<=10
1<=N<=100
大数据:
1<=T<=1000
1<=N<=10^18
样例解释
对于第二组数据,合法的方案有以下几种,(X,Y,Z)表示选择了A类纪念品中价值为X的,B类纪念品中价值为Y的,C类纪念品中价值为Z的。
(1,1,1): 3*3*3=27种
(1,2,3): 3*2*1=6种
(1,3,2): 3*1*2=6种
(2,1,3): 2*3*1=6种
(2,2,2): 2*2*2=8种
(2,3,1): 2*1*3=6种
(3,1,2): 1*3*2=6种
(3,2,1): 1*2*3=6种
(3,3,3): 1*1*1=1种
一共27+6+6+6+8+6+6+6+1=72种选择纪念品的方案
注意,如(1,1,2), (2,3,3), (3,1,3)都因为恰好选择了两件价值相同的纪念品,所以并不是一种符合要求的纪念品选择方法。
- 样例输入
-
2 1 3
- 样例输出
-
Case 1: 1 Case 2: 72
解题思路:
1. 全部方案数 有: S1 = (1+2+ ... +n) ^ 3 = ( n * (n + 1) / 2) ^ 3 ;
2. 任两个相同时,有: S2 = (1^2 + 2^2 + ... + n^2) * (1 + 2 + .. + n) = (n * (n+1) / 2) * (n * (n+1) * (2*n + 1) / 6) * 3 = S3 * (2*n + 1) ;
3. 三个相同时, 有: S3 = 1^3 + 2^3 + ... + n^3 = (1 + 2 + .. + n) ^ 2 = (n * (n + 1) / 2) ^ 2 ;
所求方案数为: S = S1 — S2 + 3 * S3 。
code:
1 #include <stdio.h> 2 const int M = 1e+9 + 7; 3 int main() 4 { 5 int T; 6 scanf("%d", &T); 7 for(int k = 0; k < T; ++k) 8 { 9 int N; 10 scanf("%d", &N); 11 unsigned long long result, sum1, sum2, sum3; 12 unsigned long long tem = N * (N + 1) / 2 % M; 13 sum3 = (tem * tem) % M; 14 sum1 = (sum3 * tem) % M; 15 sum2 = sum3 * (2 * N + 1) % M; 16 result = (3 * sum3 + sum1 - sum2 ) % M; 17 printf("Case %d: %d ", k+1, (int)result); 18 } 19 return 0; 20 }