[HDU-6467]簡單數學題
阿新 • • 發佈:2020-09-08
題目
題解
給我們了柿子,我們也只能推柿子咯......
考慮對原式進行如下變換
\[\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} \]
其中,由第二步到第三步使用了組合恆等式,如果不知道可以自行搜尋.
現在這個做法是 \(\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; }