給定 \(K\) 和 \(n\) 對 \(p_i,r_i\), 令 \(N=\prod p_i^{r_i}\), 求下式對 \(10^9+7\) 取模後的值:
\[ \sum_{k=1,k\perp N}^{N-1} k^K \]
其中 \(p_i,r_i\le 10^9, K\le 100, n\le 1000\).php
看見有學弟作了因而也作一作...c++
推了推發現可能要用Bernoulli數, 他們好神仙啊qaq...函數
下面是個人畫柿子過程, 其中 \(B_i\) 是伯努利數. 感受這題仍是有點意思的.spa
首先先進行一些套路性的捯飭求和號的過程:
\[ \begin{aligned} \text{Ans}&=\sum_{i=1}^N[i\perp N]i^K \\ &=\sum_{i=1}^N\sum_{d|i,d|N} \mu(d)i^K\\ &=\sum_{d|N}\sum_{k=1}^{\frac N d}\mu(d)(kd)^K \\ &=\sum_{d|N}\mu(d)d^K\sum_{k=1}^{\frac nd}k^K \end{aligned} \]
而後發現最後面是個天然數冪和, 能夠嘗試用伯努利數懟進去化一化.code
PS: 後來問Cage發現其實斯特林數也是能以比較簡單的形式代入天然數冪和的, 它的形式是這樣的:
\[ n^m=\sum_{k=0}^m \begin{Bmatrix}m \\ k\end{Bmatrix} n^{\underline k} \\ \begin{aligned} \sum_{x=0}^nx^m&=\sum_{x=0}^{n}\sum_{k=0}^m \begin{Bmatrix}m \\ k\end{Bmatrix} x^{\underline k} \\ &=\sum_{k=0}^m\begin{Bmatrix}m \\ k\end{Bmatrix} \sum_{x=0}^n x^{\underline k} \end{aligned} \]
而後內層和式就是混凝土數學裏面那個經典的離散微積分(差分/求和)的式子, 也就是:
\[ \Delta(x^\underline n)=nx^\underline{n-1} \\ \sum x^\underline n\delta x=\frac {x^\underline{n+1}}{n+1} \]
因此就有:
\[ \sum_{x=0}^nx^m=\sum_{k=0}^m\begin{Bmatrix}m \\ k\end{Bmatrix} \frac{x^\underline{m+1}}{m+1} \]
然而斯特林數會搞出降低冪來, 在這個題的柿子裏並非很協調的樣子, 咱們用伯努利數丟進去變換一下和式:
\[ \begin{aligned} \text{Ans}&=\sum_{d|N}\mu(d)d^K \sum_{i=0}^K\frac 1{K+1}B_i{K+1\choose i}\left (\frac N d\right)^{K+1-i}\\ &=\sum_{d|N}\sum_{i=0}^K\mu(d)d^K\frac 1{K+1}B_i{K+1\choose i}\left (\frac N d\right)^{K+1-i}\\ &=\sum_{i=0}^K\sum_{d|N}\mu(d)d^K\frac 1{K+1}B_i{K+1\choose i}\left (\frac N d\right)^{K+1-i}\\ &=\frac 1{K+1}\sum_{i=0}^KB_i{K+1\choose i}\sum_{d|N}\mu(d)d^K\left (\frac N d\right)^{K+1-i}\\ \end{aligned} \]
裏層和式裏有個 \(d^K\left (\frac N d\right)^{K+1-i}\), 顯然它就是 \(N^K\left (\frac N d\right)^{1-i}\). 這樣的話 \(N^K\) 就與和式無關了, 丟到外面:
\[ \begin{aligned} \text{Ans}&=\frac 1{K+1}\sum_{i=0}^KB_i{K+1\choose i}\sum_{d|N}\mu(d)N^K\left (\frac N d\right)^{1-i}\\ &=\frac {N^K}{K+1}\sum_{i=0}^KB_i{K+1\choose i}\sum_{d|N}\mu(d)\left (\frac N d\right)^{1-i} \end{aligned} \]
而後根據 \(\mu\) 函數的性質, 只要 \(x\) 中含有徹底平方因子則 \(\mu(x)=0\). 因而咱們考慮只枚舉質因子集合. 然而此次 \(N\) 可能很大無法直接枚舉, 嘗試DP.blog
枚舉每一個質因子 \(p_k\), 若是 \(p_k\not \mid d\) 的話至關於給和式中的每一項都乘上一個 \((p_k^{r_k})^{1-i}\). 不然 \(p_k\mid d\), 至關於和式中的每一項都乘上一個 \(-(p_k^{r_k-1})^{1-i}\) (負號是 \(\mu\) 中來的). 兩種方式構造出的值求和就是新的值. 實際上就至關於:
\[ \sum_{d|N}\mu(d)\left (\frac N d\right)^{1-i}=\prod_{k=1}^n \left (\left(p_k^{r_k}\right)^{1-i}-\left (p_k^{r_k-1}\right)^{1-i}\right) \]
因而最後總的答案就是:
\[ \frac {N^K}{K+1}\sum_{i=0}^KB_i{K+1\choose i}\prod_{k=1}^n \left (\left(p_k^{r_k}\right)^{1-i}-\left (p_k^{r_k-1}\right)^{1-i}\right) \]
算上樸素遞推Bernoulli數和快速冪, 總時間複雜度 \(O\left((K^2+nK)\log p\right)\). 這題數據數據範圍沒出滿get
#include <bits/stdc++.h> const int MAXN=1010; const int MOD=1e9+7; const int PHI=MOD-1; int n; int K; int p[MAXN]; int r[MAXN]; int B[MAXN]; // Bernoulli int inv[MAXN]; int fact[MAXN]; int C(int,int); int Pow(int,int,int); int main(){ scanf("%d%d",&K,&n); int N=1; for(int i=1;i<=n;i++){ scanf("%d%d",p+i,r+i); N=1ll*N*Pow(p[i],r[i],MOD)%MOD; } fact[0]=1; for(int i=1;i<=K+1;i++) fact[i]=1ll*fact[i-1]*i%MOD; inv[K+1]=Pow(fact[K+1],MOD-2,MOD); for(int i=K+1;i>=1;i--) inv[i-1]=1ll*inv[i]*i%MOD; B[0]=1; for(int i=1;i<=K;i++){ int sum=0; for(int j=0;j<i;j++) (sum+=1ll*C(i+1,j)*B[j]%MOD)%=MOD; B[i]=1ll*(MOD-sum)*Pow(C(i+1,i),MOD-2,MOD)%MOD; } int ans=0; for(int i=0;i<=K;i++){ int prod=1; for(int j=1;j<=n;j++) prod=1ll*prod*(Pow(p[j],1ll*r[j]*(MOD-i)%PHI,MOD)+MOD-Pow(p[j],1ll*(r[j]-1)*(MOD-i)%PHI,MOD))%MOD; (ans+=1ll*B[i]*C(K+1,i)%MOD*prod%MOD)%=MOD; } ans=1ll*ans*Pow(K+1,MOD-2,MOD)%MOD*Pow(N,K,MOD)%MOD; printf("%d\n",ans); return 0; } int C(int n,int m){ return n<0||m<0||n<m?0:1ll*fact[n]*inv[m]%MOD*inv[n-m]%MOD; } inline int Pow(int a,int n,int p){ int ans=1; while(n>0){ if(n&1) ans=1ll*a*ans%p; a=1ll*a*a%p; n>>=1; } return ans; }