我是靠谱客的博主 自由乌冬面,最近开发中收集的这篇文章主要介绍SPOJ - DIVCNT2(min_25筛),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目:SPOJ - DIVCNT2
题意:
在这里插入图片描述
min25筛时间复杂度O( n 3 4 l o g ( n ) frac{n^{frac{3}{4}}}{log(n)} log(n)n43) 。(我不会)

杜教筛的话找卷积太为难,min25筛的话限制条件相对少了。
1:函数是积性函数
2:f( p p p)表达式是一个多项式,p为质数
3:f( p k p^k pk)可以快速计算得到。
知识点来源:
weixin_30311605
https://blog.csdn.net/u013534123/article/details/82596172
https://www.cnblogs.com/zhoushuyu/p/9187319.html

首先所有的数字当作质数,从小到大把其他质数筛掉
代码也是借鉴,自己理解不太到位,直接看巨巨写的解释吧。

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
#define MAX_len 500005*4
using namespace std;
typedef long long ll;
typedef pair<int,int> PP;
long double eps=1e-9;
const ll mod=1e9+7;
const int MAXlen=2e6+10;
#define id(x) (x<=d ? id1[x] : id2[n / (x)])
ll prime[MAXlen];
ll id1[MAXlen],id2[MAXlen],val[MAXlen],B[MAXlen],ANS[MAXlen];
ll tot=0;
ll num=0;
ll n;
//MAXlen是sqrt(n)
bool vis[MAXlen];
void init()
{
num=0;
memset(vis,false,sizeof(vis));
vis[0]=vis[1]=true;
for(int i=2;i<MAXlen;i++)
{
if(!vis[i])
{
prime[++num]=i;
}
for(int j=1;j<=num&&i*prime[j]<=MAXlen;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
{
break;
}
}
}
}
ll S(ll lim,int cnt)
{
if(lim<=1||prime[cnt]>lim)
return 0;
int d=sqrt(n);
ll ans=3*(B[id(lim)]-(cnt-1));
for(int i=cnt;i<=num&&1ll*prime[i]*prime[i]<=lim;i++)
{
ll prod=prime[i];
for(int times=1;1ll*prod*prime[i]<=lim;times++,prod=1ll*prod*prime[i])
ans+=(2*times+1)*S(lim/prod,i+1)+(2*times+3);//f(p^k)
}
return ans;
}
void solve(ll lim)
{
ll d=sqrt(lim),cnt=0;
for(ll l=1,r;l<=lim;l=r+1)
{
r=lim/(lim/l);
val[++cnt]=lim/l,id(val[cnt])=cnt;
B[cnt]=val[cnt]-1;//除去1
}
for(int i=1;i<=num&&1ll*prime[i]*prime[i]<=lim;i++)
{
for(int j=1;j<=cnt&&1ll*prime[i]*prime[i]<=val[j];j++)
{
B[j]=B[j]-B[id(val[j]/prime[i])]+(i-1);
}
}
}
int main()
{
init();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld",&n);
solve(n);
ll res=S(n,1)+1;
printf("%lldn",res);
}
return 0;
}

其他:P5325
题解:click

最后

以上就是自由乌冬面为你收集整理的SPOJ - DIVCNT2(min_25筛)的全部内容,希望文章能够帮你解决SPOJ - DIVCNT2(min_25筛)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(37)

评论列表共有 0 条评论

立即
投稿
返回
顶部