【SPOJ】 —DIVCNTK(min_25筛)
Let be the number of positive divisors of .
For example, , and .
Let
Given and , find .
不会的看这个
令
考虑对于质数,
还是预处理素数个数,每次就是
#include<bits/stdc++.h>
using namespace std;
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define re register
#define pb push_back
#define cs const
#define pii pair<int,int>
#define fi first
#define se second
const int N=1000006;
#define ll unsigned long long
ll f1[N],f2[N],pr[N];
int lim,tot;
inline void init(ll k){
if(k<=1)return ;
lim=sqrt(k);tot=0;
for(int i=1;i<=lim;i++)f1[i]=i-1,f2[i]=k/i-1;
for(int p=1;p<=lim;p++){
if(f1[p]==f1[p-1])continue;pr[++tot]=p;
for(int i=1;i<=lim/p;i++)f2[i]-=f2[i*p]-f1[p-1];
for(int i=lim/p+1;1ll*i*p*p<=k&&i<=lim;i++)f2[i]-=f1[k/i/p]-f1[p-1];
for(int i=lim;i>=1ll*p*p;i--)f1[i]-=f1[i/p]-f1[p-1];
}
}
ll n,k,ans;
void calc(ll pos,ll coef,ll res){
ll g=(res<=lim)?f1[res]:f2[n/res];
ans+=(k+1)*coef*(g-f1[pr[pos-1]]);
for(int i=pos;i<=tot;i++){
if(pr[i]*pr[i]>res)return;
for(ll now=pr[i],p=1;now<=res;now*=pr[i],p++){
if(now*pr[i]<=res)calc(i+1,coef*(k*p+1),res/now);
if(p>=2)ans+=coef*(k*p+1);
}
}
}
signed main(){
int T=read();
while(T--){
scanf("%llu%llu",&n,&k);
ans=1,init(n);
calc(1,1,n);
cout<<ans<<'\n';
}
}