[HDU-6467]简单数学题
题目
题解
给我们了柿子,我们也只能推柿子咯......
考虑对原式进行如下变换
\[\begin{aligned}
F(n) &= \sum_{i=1}^n (i \times \sum_{j=i}^n C_j^i) \\
&= \sum_{j=1}^n\sum_{i=1}^j i\times C_{j}^i \\
&= \sum_{j=1}^n j\times 2^{j-1}
\end{aligned}
\]
其中,由第二步到第三步使用了组合恒等式 \(\sum_{i=0}^nC_n^i\times i=n\times 2^{n-1}\) ,如果不知道可以自行搜索.
现在这个做法是 \(\mathcal O(Tn)\) 的,对于 \(n\le 10^{18}\)...我们还需要考虑优化。
注意到 \(\sum\) 内部的 \(2\) 缺少了一个,我们考虑将其补足,有
\[\begin{aligned}
2F(n)&=2\sum_{j=1}^n j\times 2^{j-1} \\
&=\sum_{j=1}^n j\times 2^j
\end{aligned}
\]
考虑与原式 \(F(n)=\sum_{j=1}^n j\times 2^{j-1}\) 作差,得到
\[\begin{aligned}
2F(n)-F(n) &=\sum_{j=1}^n j\times 2^j-\sum_{j=1}^n j\times 2^{j-1} \\
&=n\times 2^n-\sum_{i=0}^{n-1}2^i \\
&= n\times 2^n-(2^n-1) \\
&= (n-1)\times 2^n+1=F(n)
\end{aligned}
\]
这就是通项公式了,直接带 \(n\) 进去算即可。
代码
#include<cstdio>
#define rep(i,__l,__r) for(signed i=(__l),i##_end_=(__r);i<=i##_end_;++i)
#define fep(i,__l,__r) for(signed i=(__l),i##_end_=(__r);i>=i##_end_;--i)
#define erep(i,u) for(signed i=tail[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writc(a,b) fwrit(a),putchar(b)
#define mp(a,b) make_pair(a,b)
#define fi first
#define se second
typedef long long LL;
// typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef unsigned uint;
#define Endl putchar('\n')
// #define int long long
// #define int unsigned
// #define int unsigned long long
#define cg (c=getchar())
template<class T>inline void read(T& x){
char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
if(f)x=-x;
}
template<class T>inline T read(const T sample){
T x=0;char c;bool f=0;
while(cg<'0'||'9'<c)f|=(c=='-');
for(x=(c^48);'0'<=cg&&c<='9';x=(x<<1)+(x<<3)+(c^48));
return f?-x:x;
}
template<class T>void fwrit(const T x){//just short,int and long long
if(x<0)return (void)(putchar('-'),fwrit(-x));
if(x>9)fwrit(x/10);
putchar(x%10^48);
}
template<class T>inline T Max(const T x,const T y){return x<y?y:x;}
template<class T>inline T Min(const T x,const T y){return x<y?x:y;}
template<class T>inline T fab(const T x){return x>0?x:-x;}
inline int gcd(const int a,const int b){return b?gcd(b,a%b):a;}
inline LL mulMod(const LL a,const LL b,const LL mod){//long long multiplie_mod
return ((a*b-(LL)((long double)a/mod*b+1e-8)*mod)%mod+mod)%mod;
}
const int mod=1000000007;
const int phimod=mod-1;
LL n;
inline int qkpow(int a,LL n){
n%=phimod;
int ret=1;
for(;n>0;n>>=1,a=1ll*a*a%mod)if(n&1)ret=1ll*ret*a%mod;
return ret;
}
inline int calc(const LL n){
return ((n-1)%mod*qkpow(2,n)%mod+1)%mod;
}
signed main(){
while(~scanf("%lld",&n))writc(calc(n),'\n');
return 0;
}