SP19975 APS2 - Amazing Prime Sequence (hard)
前置知识:Min_25 筛。
默认读者已经掌握 Min_25 筛。
题意
给定
其中
思路
分别考虑质数与合数的贡献。
质数的贡献为:
令
利用 Min_25 筛的第一部分即可求解。
合数的贡献为:
枚举所有可能的
令
考虑 Min_25 筛第一部分中
注意到
在递推过程中统计贡献即可。
时间复杂度为
Code
#include<bits/stdc++.h>
#define int unsigned long long
const int B=1.2e6+10;
using namespace std;
int T;
int n,b,ans;
int cnt,p[B];
bool vis[B];
int s1[B],s2[B];
int tot,w[B<<1];
int id1[B],id2[B];
int g1[B<<1],g2[B<<1];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')ret=ret*10+(ch&15),ch=getchar();
return ret*f;
}
int _sqrt(int x){
int ret=floor(sqrtl(x));
while((ret+1)*(ret+1)<=x)ret++;
return ret;
}
int get_id(int _n){
if(_n<=b)return id1[_n];
return id2[n/_n];
}
int _sum(int _n){
if(_n&1)return (_n+1)/2*_n;
return _n/2*(_n+1);
}
void _init(){
cnt=tot=0;
for(int i=1;i<=b;i++)p[i]=vis[i]=s1[i]=s2[i]=id1[i]=id2[i]=0;
for(int i=1;i<=b*2;i++)w[i]=g1[i]=g2[i]=0;
for(int i=2;i<=b;i++){
if(!vis[i]){
p[++cnt]=i;
s1[cnt]=s1[cnt-1]+1;
s2[cnt]=s2[cnt-1]+i;
}
for(int j=1;j<=cnt&&i*p[j]<=b;j++){
vis[i*p[j]]=1;
if(!(i%p[j]))break;
}
}
for(int l=1,r;l<=n;l=r+1){
r=n/(n/l);
int _n=n/l;
w[++tot]=_n;
if(_n<=b)id1[_n]=tot;
else id2[n/_n]=tot;
g1[tot]=_n-1;
g2[tot]=_sum(_n)-1;
}
for(int k=1;k<=cnt;k++){
for(int i=1;i<=tot&&p[k]*p[k]<=w[i];i++){
int id=get_id(w[i]/p[k]);
g1[i]-=g1[id]-s1[k-1];
g2[i]-=p[k]*(g2[id]-s2[k-1]);
if(i==1)ans+=p[k]*(g1[id]-s1[k-1]);
}
}
}
void _solve(){
n=read();
b=_sqrt(n);
ans=0;
_init();
ans+=g2[1];
printf("%llu\n",ans);
}
signed main(){
T=read();
while(T--)_solve();
return 0;
}