HDU 6467.简单数学题-数学题 (“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛)

简单数学题

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 580    Accepted Submission(s): 257


Problem Description
已知

F(n)=i=1n(i×j=inCij)


求 F(n) mod 1000000007
 

 

Input
多组输入,每组输入占一行,包含一个整数n(1 <= n <= 1e18)。
数据不超过300000组。
 

 

Output
对于每组输入,输出一行,包括一个数代表答案。
 

 

Sample Input
5 100
 

 

Sample Output
129 660756544
 

 

Source
 
写的时候,推了好几次,每次都能优化一点点,最后发现就是一个公式。
优化过程代码中注释掉了。
 

推的过程中用到的一个公式

对于C(n,k)*k求和,k从1到n
n为常量,要求和的式子如下:
1*C(n,1)+2*C(n,2)+3*C(n,3)+.+n*C(n,n)
其中,C(n,k)的意义是组合数,n为下标,k为上标
最终结果为化简后的式子

C(n,k)*k
=k*n!/[(n-k)!k!]
=n*(n-1)!/[(k-1)!(n-k)!]
=n*C(n-1,k-1)
1*C(n,1)+2*C(n,2)+3*C(n,3)+.+n*C(n,n)
=n[C(n-1,0)+C(n-1,1)+C(n-1,2)+.+C(n-1,n-1)]
=n*2^(n-1)

 
代码:
 1 //6467
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5 const int maxn=1e5+10;
 6 const int mod=1000000007;
 7 //
 8 //ll fac[maxn],inv[maxn];
 9 //
10 //void init()
11 //{
12 //    fac[0]=fac[1]=1;
13 //    inv[0]=inv[1]=1;
14 //    for(ll i=2;i<maxn;i++)
15 //    {
16 //        fac[i]=fac[i-1]*i%mod;
17 //        inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
18 //    }
19 //    for(ll i=2;i<maxn;i++)
20 //        inv[i]=inv[i-1]*inv[i]%mod;
21 //}
22 //ll C(ll x,ll y)
23 //{
24 //    if(y>x) return 0;
25 //    if(y==0||x==0) return 1;
26 //    return fac[x]*inv[y]%mod*inv[x-y]%mod;
27 //}
28 
29 ll pow_mod(ll a,ll b){
30      ll ans=1;
31      while(b){
32          if(b%2==1){
33              ans=ans*a%mod;
34          }
35          a=a*a%mod;
36          b=b/2;                              //这里是转化为二进制之后的进位---左进位
37      }
38      return ans;
39  }
40 
41 //ll a[maxn];
42 
43 int main()
44 {
45 //    init();
46 //    for(int i=1;i<=1e3;i++){
47 ////        for(int j=1;j<=i;j++){
48 ////            a[i]=(a[i]+j*C(i,j)%mod)%mod;
49 ////        }
50 //        a[i]=i*pow_mod(2,(i-1))%mod;
51 //        a[i]=(a[i]+a[i-1])%mod;
52 //        //a[i]+=a[i-1];
53 //    }
54     ll n;
55     while(~scanf("%lld",&n)){
56         ll ans=(((n-1)%mod)*pow_mod(2,n)+1)%mod;
57         cout<<ans<<endl;
58     }
59 }

 

 

 

posted @ 2019-03-22 20:01  ZERO-  阅读(273)  评论(0编辑  收藏  举报