我是靠谱客的博主 自由乌冬面,这篇文章主要介绍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

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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#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内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部