【SPOJ】 —DIVCNTK(min_25筛)

传送门

Let σ0(n)\sigma_0(n) be the number of positive divisors of nn.

For example, σ0(1)=1\sigma_0(1) = 1, σ0(2)=2\sigma_0(2) = 2 and σ0(6)=4\sigma_0(6) = 4.

Let Sk(n)=i=1nσ0(ik).S_k(n) = \sum _{i=1}^n \sigma_0(i^k).

Given nn and kk, find Sk(n) mod 264S_k(n) \bmod 2^{64}.

不会min25min_{25}的看这个

f(p)=σ0(pk)f(p)=\sigma_0(p^k)

考虑对于质数ppf(p)=k+1,f(pc)=kc+1f(p)=k+1,f(p^c)=kc+1

还是预处理素数个数gg,每次就是g(n)k+1g(n)*k+1

#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';
	}
}
posted @ 2019-07-28 14:55  Stargazer_cykoi  阅读(151)  评论(0编辑  收藏  举报