bzoj 2721
阿新 • • 發佈:2018-11-01
題解:首先推一發式子:
原式:
通分,移項:
開啟,合併:
再移項,得:
設:
那麼:
代入:
化簡:
因為x是整數,所以x的數量顯然為能使取得整數的t的個數,也就是求的約數個數
而根據約數個數和公式(設一個數)
可以將前n個數質因子分解,然後將質因子的冪次相乘,最後將所有冪次*2+1後乘在一起即可。
#include <cstdio> #include <cmath> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <stack> #define ll long long #define mode 1000000007 #define maxn 1000000 using namespace std; ll fac[1000005]; ll pri[1000005]; bool used[1000005]; int tot=0; int n; void init() { scanf("%d",&n); for(int i=2;(ll)i*i<=n;i++) { if(!used[i]) { pri[++tot]=i; } for(int j=1;j<=tot&&(ll)i*pri[j]<=n;j++) { used[i*pri[j]]=1; if(i%pri[j]==0) { break; } } } for(int i=2;i<=n;i++) { int t=i; for(int j=1;(ll)pri[j]*pri[j]<=t&&j<=tot;j++) { while(t%pri[j]==0) { fac[pri[j]]++; t/=pri[j]; if(fac[pri[j]]>=mode) { fac[pri[j]]-=mode; } } } if(t!=1) { fac[t]++; if(fac[t]>=mode) { fac[t]-=mode; } } } ll ans=1; for(int i=1;i<=n;i++) { fac[i]<<=1; fac[i]%=mode; ans*=(fac[i]+1); ans%=mode; } printf("%lld\n",ans); } int main() { init(); return 0; }