# loj 572 Misaka Network 与求和 —— min_25筛

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef unsigned int uint;
typedef long long ll;
int const xn=1e6+5;
int n,m,K,pri[xn],cnt,w[xn],sqr;
uint prk[xn],h[xn],G[xn];
bool vis[xn];
uint pw(uint a,int b){uint ret=1; for(;b;b>>=1,a=a*a)if(b&1)ret=ret*a; return ret;}
void init(int mx)
{
for(int i=2;i<=mx;i++)
{
if(!vis[i])pri[++cnt]=i,prk[cnt]=pw(i,K);
for(int j=1;j<=cnt&&(ll)i*pri[j]<=mx;j++)
{
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
}
int Id(int x)
{
if(x>sqr)return n/x;
return m-x+1;
}
uint F(int x,int y)
{
if(pri[y]>x)return 0;
uint ret=0;
for(int i=y;i<=cnt&&(ll)pri[i]*pri[i]<=x;i++)//ll
for(ll p0=pri[i];p0*pri[i]<=x;p0*=pri[i])
ret+=F(x/p0,i+1)+(uint)prk[i]*(h[Id(x/p0)]-i+1);
return ret;
}
uint S(int x)
{
if(G[Id(x)]!=-1)return G[Id(x)];
uint ret=F(x,1)+h[Id(x)];
for(int i=2,j;i<=x;i=j+1)j=x/(x/i),ret-=(j-i+1)*S(x/i);
return G[Id(x)]=ret;
}
int main()
{
scanf("%d%d",&n,&K); sqr=sqrt(n); init(sqr);
for(int i=1,j;i<=n;i=j+1)
{w[++m]=n/i; j=n/w[m]; h[m]=w[m]-1;}
for(int j=1;j<=cnt;j++)
for(int i=1;i<=m&&(ll)pri[j]*pri[j]<=w[i];i++)
h[i]=h[i]-h[Id(w[i]/pri[j])]+j-1;//w[i]
memset(G,-1,sizeof G);
uint ans=0;
for(int T=1,nxt;T<=n;T=nxt+1)
{
nxt=n/(n/T);
ans+=(uint)(n/T)*(n/T)*(S(nxt)-S(T-1));
}
printf("%u\n",ans);//
return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef unsigned int uint;
typedef long long ll;
int const xn=1e6+5;
int n,m,K,pri[xn],cnt,w[xn],sqr;
uint prk[xn],h[xn],G[xn],f[xn];
bool vis[xn];
uint pw(uint a,int b){uint ret=1; for(;b;b>>=1,a=a*a)if(b&1)ret=ret*a; return ret;}
void init(int mx)
{
for(int i=2;i<=mx;i++)
{
if(!vis[i])pri[++cnt]=i,prk[cnt]=pw(i,K);
for(int j=1;j<=cnt&&(ll)i*pri[j]<=mx;j++)
{
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
}
int Id(int x)
{
if(x>sqr)return n/x;
return m-x+1;
}
void getf()
{
for(int i=cnt;i;i--)
for(int j=1;j<=m&&(ll)pri[i]*pri[i]<=w[j];j++)
for(ll p0=pri[i];p0*pri[i]<=w[j];p0*=pri[i])
f[j]+=f[Id(w[j]/p0)]+(uint)prk[i]*(h[Id(w[j]/p0)]-i+1);
}
uint S(int x)
{
if(G[Id(x)]!=-1)return G[Id(x)];
uint ret=f[Id(x)]+h[Id(x)];
for(int i=2,j;i<=x;i=j+1)j=x/(x/i),ret-=(j-i+1)*S(x/i);
return G[Id(x)]=ret;
}
int main()
{
scanf("%d%d",&n,&K); sqr=sqrt(n); init(sqr);
for(int i=1,j;i<=n;i=j+1)
{w[++m]=n/i; j=n/w[m]; h[m]=w[m]-1;}
for(int j=1;j<=cnt;j++)
for(int i=1;i<=m&&(ll)pri[j]*pri[j]<=w[i];i++)
h[i]=h[i]-h[Id(w[i]/pri[j])]+j-1;//w[i]
memset(G,-1,sizeof G);
uint ans=0; getf();
for(int T=1,nxt;T<=n;T=nxt+1)
{
nxt=n/(n/T);
ans+=(uint)(n/T)*(n/T)*(S(nxt)-S(T-1));
}
printf("%u\n",ans);//
return 0;
}

posted @ 2019-01-17 20:56  Zinn  阅读(225)  评论(0编辑  收藏  举报