hdu--5139--bc

这题 很多人用的都是 离线处理的方法。

比赛的时候 就没想到这个方法。

一直在mle tle之间徘徊。。 porker的这个处理数组方法很好

我本来是1-1e7的数组范围存下的是每个f[n]的值

现在我用一个 1-1e6的数组来表示f[n] , g[n]            g[n]就是n的阶乘

因为 f[n] = f[n-1] * g[n]

那么当我的数组范围是开到1e6的时候 就是说0存的是n=1的解 1存的是n=10的解 10 存的是n=100的解 11存的是n=110的解

那么你可以发现 我任意一个要查询的数n 都将落在[n/10,n/10+1)这个区间内的某个数之内 就是说15会在[1,2)之间

45会在[4,5)之内。

这种方法不仅适用于本题 对于某些对内存要求很高的 同时你的方法足够满足这个时间的情况下 可以这样来解决

同时 这边你的数组最好开成int来计算 虽然当我们进行上面步骤之后 也不会mle  但是为了保险开成int来保存

但是 中途计算的时候 会爆 int所以我们需要先转换为LL 最后计算完成之后在强制转换为int

ok 贴下代码 离线的明天再贴 打游戏啦。。

 1 #include <iostream>
 2 using namespace std;
 3
 4 typedef __int64 LL;
 5 const int size = 10000010;
 6 const int mod = 1000000007;
 7 LL n;
 8 int f[1000010];
 9 int g[1000010];
10
11 void init( )
12 {
13     f[0] = g[0] = 1;
14     int now , next;
15     now = 1;
16     int sum , ans;
17     sum = 1;
18     for( int i = 2 ; i<=size-9 ; i++ )
19     {
20         next = (int)( ( 1LL * ( now%mod ) * i ) % mod);
21         ans = (int)( ( 1LL * (sum%mod) * (next%mod) ) % mod);
22         now = next;
23         sum = ans;
24         if( i%10==0 )
25            {
26            f[i/10] = ans;
27               g[i/10] = next;
28         }
29     }
30 }
31
32 int main()
33 {
34     init( );
35     LL temp , sum , ans , now , next;
36     while( ~scanf("%d",&n) )
37     {
38         if( n%10==0 )
39         {
40             printf( "%d\n",f[n/10] );
41         }
42         else
43         {
44             temp = n/10;
45             ans = 1LL * f[n/10];
46             sum = ans;
47             now = 1LL * g[n/10];
48             for(  LL i = temp*10+1 ; i<=n ; i++ )
49             {
50                 next = (int)( ( now%mod ) * i % mod );
51                 ans = (int)(  (sum%mod) * (next%mod) % mod );
52                 now = next;
53                 sum = ans;
54             }
55             printf( "%I64d\n",ans);
56         }
57     }
58     return 0;
59 }

时间: 2024-07-31 21:59:53

hdu--5139--bc的相关文章

hdu 5139 Formula

http://acm.hdu.edu.cn/showproblem.php?pid=5139 思路:这道题要先找规律,f(n)=n!*(n-1)!*(n-2)!.....1!;  不能直接打表,而是离线处理,一次性处理出来. 1 #include <cstdio> 2 #include <cstring> 3 #include <map> 4 #include <algorithm> 5 #define ll long long 6 #define mod

hdu 5234 (bc #42 C)Happy birthday(dp)

Happy birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 672    Accepted Submission(s): 302 Problem Description Today is Gorwin’s birthday. So her mother want to realize her a wish. Gorwin

hdu 5364 (bc#50 1001) Distribution money

Distribution money Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 276    Accepted Submission(s): 163 Problem Description AFA want to distribution her money to somebody.She divide her money into

hdu 5365 (bc #50 1002 )Run

Run Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 594    Accepted Submission(s): 265 Problem Description AFA is a girl who like runing.Today,he download an app about runing .The app can record

hdu 5366 (bc #50 1003) The mook jong

The mook jong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 269    Accepted Submission(s): 205 Problem Description ![](../../data/images/C613-1001-1.jpg) ZJiaQ want to become a strong man, so

hdu 5139 Formula(离线处理)

Formula Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1200    Accepted Submission(s): 415 Problem Description You are expected to write a program to calculate f(n) when a certain n is given.

hdu 5203 &amp;&amp; BC Round #37 1002

代码参考自:xyz111 题意: 众所周知,萌萌哒六花不擅长数学,所以勇太给了她一些数学问题做练习,其中有一道是这样的:勇太有一根长度为n的木棍,这个木棍是由n个长度为1的小木棍拼接而成,当然由于时间放置的久了,一些小木棍已经不牢固了,所以勇太想让六花把这个木棍分成正整数长度的4段,其中有3段要没有不牢固的小木棍,勇太希望这3段木棍的长度和可以最大.同时六花希望在满足勇太要求的情况下让这三根木棍能拼成一个三角形,请问萌萌哒六花有多少种可行的分割方案呢?当然,这个问题对于萌萌哒六花来说实在是太难了

HDU 5139 Formula --离线处理

题意就不说了,求公式. 解法: 稍加推导能够得出 : f(n) = n! * f(n-1) , 即其实是求: ∏(n!)  ,盲目地存下来是不行的,这时候看见条件: 数据组数 <= 100000, 那么我们可以离线做,先把他们存下来,然后再从小到大扫一边, 也就是最多10000000次乘法的复杂度.然后离线输出即可. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <

HDU 5139 Formula 卡内存

题目就是求这个 n达到10^7,测试数据组数为10^5 为了防止TLE,一开始把每个n对应的值先求出来,但发现竟然开不了10^7的数组(MLE),然后就意识到这是第一道卡内存的题目... 只能离线做,把每个n从小到大排序,然后从小到大依次求,然后把结果存下来,最后排回去输出. #include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm&

hdu 5139 Formula (找规律+离线处理)

Formula Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 206    Accepted Submission(s): 83 Problem Description f(n)=(∏i=1nin−i+1)%1000000007You are expected to write a program to calculate f(n) w