题解 P4626 【一道水题 II】
这范围明摆着分块打表啊...
答案就是
考虑
long long solve(int p)
{
long long ans=p;
while(ans*p<=n)ans=ans*p;
return ans;
}
然后再注意到如果
复杂度
打表程序
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e8,mod=1e8+7;
const int blo=1e6;
int w[5000],prime[N],cnt;
bool p[N+5];
void make()
{
for(int i=1;i<=100;i++)w[i]=1;
for(int i=2;i<=N;i++)
{
int id=(i-1)/blo+1;
if(!p[i])prime[++cnt]=i,w[id]=1ll*w[id]*i%mod;
for(int j=1;j<=cnt&&i*prime[j]<=N;j++)
{
p[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
w[1]=1;for(int i=3;i<=100;i++)w[i]=1ll*w[i]*w[i-1]%mod;
}
int main()
{
freopen("data.txt","w",stdout);
make();
for(int i=1;i<=100;i++)printf("%d,",w[i]);
}
提交程序
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int blo=1e6,N=5e6,mod=1e8+7;
const int W[500]={0,1,4279041,78522927,97275812,6626498,90103459,19755829,89404363,31420837,78259116,79495350,63384896,76365496,77671792,60888616,14364168,69179499,73237343,47511561,98202707,9638787,8923490,19377161,14025453,83914297,99211028,91698985,11861010,41728948,85011248,2957451,96835040,13279739,65389333,35674577,69539515,43558531,90167843,65612508,96727630,84411969,10432978,81144826,76822534,44673268,48780356,42026053,71419640,925833,75468296,56122076,11730540,24214526,57670707,87561236,60795551,16258057,38969193,93135220,99449198,86687779,48716439,54282180,9747238,6014664,88132693,90624798,78394444,54259153,2424434,71634841,6763549,80339105,74090298,10910559,39590831,57807866,78084208,54389248,4052287,74604335,99190428,89368783,73470487,32097770,29222100,30538785,3048397,89311543,48798411,36895907,88691881,24323948,4724247,97882710,84490696,93965490,66087028,92642640,55440368};
int prime[N],p[N],n,cnt;
void make(int n)
{
for(int i=2;i<=n;i++)
{
if(!p[i])prime[++cnt]=i;
for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
{
p[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
long long solve(int p)
{
long long ans=p;
while(ans*p<=n)ans=ans*p;
return ans;
}
int main()
{
scanf("%d",&n);
if(n<=blo)
{
make(n);int ans=1;
for(int i=1;i<=cnt;i++)
ans=solve(prime[i])*ans%mod;
printf("%d\n",ans);
}
else
{
make(blo);int ans=1;
for(int i=1;i<=cnt;i++)
ans=solve(prime[i])*ans%mod;
int id=(n-1)/blo;ans=1ll*ans*W[id]%mod;
long long L=id*blo+1,R=n;for(int i=0;i<=R-L;i++)p[i]=0;
for(int i=1;i<=cnt&&prime[i]*prime[i]<=R;i++)//区间筛
{
int l=L/prime[i]*prime[i];if(l<L)l+=prime[i];
while(l<=R)p[l-L]=1,l+=prime[i];
}
int tmp=0;
for(int i=L;i<=R;i++)
if(!p[i-L])++tmp,ans=1ll*ans*i%mod;
printf("%d\n",ans);
}
}
比第二快了二十多倍吧(雾