水幾個簡單PE題解,難的留着以後出(ban)。。。
題意:求,,
這題就看着嚇人點,,,瞎jb化化就沒了…
把中所有的組合數拆開,即
對於可以在的複雜度唯一分解
容(shu)易(xue)發(chang)現(shi)是個積性函數
那麼求出每個乘一塊就完了,並且,可以直接求出
然後裏面直接枚舉就夠了。。。總複雜度大概?反正二十多秒跑出來了
代碼如下:
#include<bits/stdc++.h>
#define N 5000020
using namespace std;
const int MOD=1e9+7;
typedef long long LL;
int n,top;
int prime[N],f[N][30];
LL val[N],tmp,ans;
bool pd[N];
inline void prime_shaker(int n){
for(int i=2;i<=n;i++){
if(!pd[i]) prime[++top]=i;
for(int j=1;j<=top && 1ll*i*prime[j]<=n;j++){
pd[i*prime[j]]=true;
if(i%prime[j]==0) break;
}
}
}
inline void divide(int x,int k){
for(int i=1;i<=top && 1ll*prime[i]*prime[i]<=x;i++)
while(x%prime[i]==0){
val[i]+=k;
x=x/prime[i];
}
if(x!=1){
int t=lower_bound(prime+1,prime+top+1,x)-prime;
val[t]+=k;
}
}
inline int qpow(int x,int k){
int sum=1;
while(k){
if(k&1) sum=1ll*sum*x%MOD;
x=1ll*x*x%MOD;
k>>=1;
}
return sum;
}
int main(){
scanf("%d",&n);prime_shaker(n);
for(int i=1;i<=top;i++)
for(int j=f[i][0]=1;j<=20;j++)
f[i][j]=(f[i][j-1]+qpow(prime[i],j))%MOD;
for(int i=1;i<=n;i++){
for(int j=1;j<=top;j++) val[j]=0;
for(int j=2;j<=i;j++) divide(j,2*j-i-1);
tmp=1;
for(int j=1;j<=top;j++){
LL t=1ll*(qpow(prime[j],val[j]+1)+MOD-1)*qpow(prime[j]-1,MOD-2)%MOD;
///for(int l=1;l<=val[j];l++) t=(t+qpow(prime[j],l))%MOD;
tmp=(1ll*tmp*t)%MOD;
}
ans=(ans+tmp)%MOD;
}
printf("%lld\n",ans);
return 0;
}