New \ (O(k+\log n) \) approach.
Consider calculating the contribution of each monkey to the answer.
Make a table:
1 1 2 4 8 16 32 ...
It can be seen that the contribution of the $I $monkey to the answer is \ (i^k \times 2^{n-i-1} \), in particular, the contribution of the last monkey to the answer is \ (n^k \).
Written as persimmon:
We just need to calculate \ (\ sum {I = 1} ^ {n-1} I ^ k \ times (2 ^ {- 1}) ^ I \).
Then we found that the persimmon was CODECHEF qpolysum, and then we finished it.
Let's write it down
qpolysum is different from this question, that is \ (i \) starts from \ (0 \), but it doesn't make any difference, because what you want to lose is a \ (0 \)(
In this question, it is equivalent to \ (m=2^{-1} \).
However, this practice guessed a very strange conclusion, and the practice came from the school OJ discussion area(
We guess that \ (s (n) = m ^ n (g (n) - G (0) \), where \ (G(x) \) is a polynomial of no more than \ (k \).
Proof can see This blog I won't tell you I can't understand
Then make a difference:
Let \ (G(0)=x \), then we use \ (x \) to represent \ (G(n) \) when \ (n \) is any value.
Because the highest degree of this polynomial is \ (k \), and the difference for a \ (k \) polynomial is \ (0 \) after \ (k+1 \) times, we obtain the following result after \ (G(x) \) difference \ (k+1 \) times:
We can use \ (x \) to represent \ (G(0) \sim G(k+1) \), then solve a unary linear equation to obtain \ (x \), and bring in the value of \ (G(1) \sim G(k+1) \).
Now we can use Lagrange interpolation to calculate \ (G(n) \), and the answer is \ (m^nG(n)-G(0) \).
\(i^k \) can use linear sieve, so the complexity is \ (O(k+\log n) \).
what? You stuck my space\ (10 \) too many arrays???
In fact, it can be reduced to \ (7 \) arrays of \ (\ rm int \) and \ (1 \) arrays of \ (\ rm bool \).
My linear sieve directly records the minimum prime factor rather than whether it is a prime number, which can be changed to the latter.
Then, when using the \ (q \) and \ (p \) arrays, the \ (x \) and \ (y \) arrays will no longer be used, so you can directly use \ (x \) and \ (y \) instead of \ (q \) and \ (p \).
code:
#include<cstdio> #include<cctype> const int M=2e7+5,mod=1e9+7; int k,n1,n2,top,x[M],y[M],idk[M],pri[M],fac[M],ifac[M];bool zhi[M]; int G[M]; inline void read(){ char s;long long t1,t2; while(isdigit(s=getchar())){ t1=n1*10ll+(s^48);n1=t1>=mod?t1%mod:t1; t2=n2*10ll+(s^48);n2=t2>=mod-1?t2%(mod-1):t2; } } inline int Add(const int&a,const int&b){ return a+b>=mod?a+b-mod:a+b; } inline int Del(const int&a,const int&b){ return b>a?a-b+mod:a-b; } inline int C(const int&n,const int&m){ return 1ll*fac[n]*ifac[m]%mod*ifac[n-m]%mod; } inline int pow(int a,int b){ int ans=1; for(;b;b>>=1,a=1ll*a*a%mod)if(b&1)ans=1ll*ans*a%mod; return ans; } inline void sieve(const int&M){ register int i,j,x;idk[1]=1; for(i=2;i<=M;++i){ if(!zhi[i])pri[++top]=i,idk[i]=pow(i,k); for(j=1;j<=top&&(x=i*pri[j])<=M;++j){ idk[x]=1ll*idk[i]*idk[pri[j]]%mod;zhi[x]=true; if(!(i%pri[j]))break; } } } inline int Inter(const int&n){ register int i,tmp,ans=0; x[0]=y[k+2]=1; for(i=1;i<=k+1;++i)x[i]=1ll*x[i-1]*Del(n,i)%mod; for(i=k+1;i>=1;--i)y[i]=1ll*y[i+1]*Del(n,i)%mod; for(i=1;i<=k+1;++i){ if(k+1-i&1)ans=Del(ans,1ll*1ll*x[i-1]*y[i+1]%mod*G[i]%mod*ifac[i-1]%mod*ifac[k+1-i]%mod); else ans=Add(ans,1ll*1ll*x[i-1]*y[i+1]%mod*G[i]%mod*ifac[i-1]%mod*ifac[k+1-i]%mod); } return ans; } signed main(){ register int i,X=0,Y=0; fac[0]=fac[1]=ifac[0]=ifac[1]=1;read();scanf("%d",&k);sieve(k+1);x[0]=1;y[0]=0; for(i=1;i<=k+1;++i)x[i]=Add(x[i-1],x[i-1]),y[i]=Add(y[i-1],idk[i-1]),y[i]=Add(y[i],y[i]); for(i=2;i<=k+1;++i)fac[i]=1ll*fac[i-1]*i%mod,ifac[i]=1ll*(mod-mod/i)*ifac[mod%i]%mod; for(i=2;i<=k+1;++i)ifac[i]=1ll*ifac[i-1]*ifac[i]%mod; for(i=0;i<=k+1;++i){ if(i&1){ X=Add(X,1ll*C(k+1,i)*x[k+1-i]%mod); Y=Add(Y,1ll*C(k+1,i)*y[k+1-i]%mod); } else{ X=Del(X,1ll*C(k+1,i)*x[k+1-i]%mod); Y=Del(Y,1ll*C(k+1,i)*y[k+1-i]%mod); } } G[0]=mod-1ll*Y*pow(X,mod-2)%mod; for(i=1;i<=k+1;++i)G[i]=Add(1ll*x[i]*G[0]%mod,y[i]); printf("%d",Add(1ll*Del(1ll*pow(500000004,n2)*Inter(n1)%mod,G[0])*pow(2,n2-1)%mod,pow(n1,k))); }