Formula
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 384 Accepted Submission(s): 160
Problem Description
f(n)=(∏i=1nin−i+1)%1000000007
You are expected to write a program to calculate f(n) when a certain n is given.
Input
Multi test cases (about 100000), every case contains an integer n in a single line.
Please process to the end of file.
[Technical Specification]
1≤n≤10000000
Output
For each n,output f(n) in a single line.
Sample Input
Sample Output
Source
BestCoder Round #21
分析:
先给出题解:
找规律
f(1)=1
f(2)=1*1*2=(1)*(1*2)=1!*2!
f(3)=1*1*1*2*2*3=(1)*(1*2)*(1*2*3)=1!*2!*3!
式子可以简化为
f(n)=∏i=1n(n!)%MOD
,直接打表不行,会超内存,可以对数据进行离线处理。排好序之后从小到大暴力。ClogC+10000000 ,C为case数目。
当时做的时候直接求,TLE , 又进一步优化用分治法求 n^m, 还是TLE。坑,最后想到应该有技巧,对于 n = 100
f( n ) = 1^99 * 2^98 * 3^97 * 4^96 *……* 99^2 * 100 = ( 1^98 * 2^97 * 3^96 * 4^95 *……* 99) * 100! = …
最终结果为: f( n ) = 1! * 2! * 3! *……*100!
带着激动的心情提交代码,又是 TLE!脑力枯竭,还有30分钟,我选择了放弃。
比赛结束后,题解上说离线处理,以前听过离线处理,应该是那样^-^……
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#define for1( i , a , b ) for( int i = a ; i <= b ; i++ )
using namespace std ;
const int maxn = 10000010 , mod = 1000000007 ;
int a[ maxn ] , s[ maxn ] , f[ maxn ] ;
int main()
{
int n = -1 ;
while( ~scanf( "%d" , &a[ ++n ] ) ) s[ n ] = a[ n ] ; // s 保持数据原来顺序
sort( a , a + n ) ; //由小到大排序
long long Sum = 1 , sum = 1 , k = 1 ;
for1( i , 0 , n - 1 ) { //暴力求解
for1( j , k , a[ i ] ) {
sum = sum * j % mod ;
Sum = Sum * sum % mod ;
}
k = a[ i ] + 1 ;
f[ a[ i ] ] = Sum ; //保存结果
}
for1( i , 0 , n - 1 ) printf( "%d\n" , f[ s[ i ] ] ) ; //按输入顺序输出结果
return 0;
}