【51nod1222】最小公倍数计数

Source

51nod1222

Solution

请先思考后再展开

tjz
$O(n^{\frac{2}{3}})$
(花了点时间,忘记第二个函数在x=0是没有定义的了)

洲阁筛、杜教筛做法

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
98
99
100
101
102
103
104
105
106
//Zory-2019
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
#include<deque>
using namespace std;
namespace mine
{
typedef long long ll;
#define double long double
const int INF=0x3f3f3f3f;
const ll LLINF=0x3f3f3f3f3f3f3f3fll;
ll qread()
{
ll ans=0;char c=getchar();int f=1;
while(c<'0' or c>'9') {if(c=='-') f=-1;c=getchar();}
while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
return ans*f;
}
void write(ll num)
{
if(num<0) {num=-num;putchar('-');}
if(num>9) write(num/10);
putchar('0'+num%10);
}
void write1(ll num){write(num);putchar(' ');}
void write2(ll num){write(num);puts("");}
#define FR first
#define SE second
#define MP make_pair
#define pr pair<int,int>
#define PB push_back
#define vc vector
void chmax(int &x,const int y) {x=x>y?x:y;}
void chmin(ll &x,const int y) {x=x<y?x:y;}
const int MAX_N=1e6+10;
ll MOD;
void add(int &x,int y) {x+=y;if(x>=MOD) x-=MOD;if(x<0) x+=MOD;}
ll qpower(ll x,ll e)
{
ll ans=1;
while(e)
{
if(e&1) ans=ans*x%MOD;
x=x*x%MOD;e>>=1;
}
return ans;
}
ll inv(ll x){return qpower(x,MOD-2);}
bool mark[MAX_N];int prime[MAX_N/10],pp=0;
int mu[MAX_N];
void pre()
{
mu[1]=1;
for(int i=2;i<MAX_N;i++)
{
if(!mark[i]) prime[++pp]=i,mu[i]=-1;
for(int j=1;j<=pp and (ll)i*prime[j]<MAX_N;j++)
{
int t=i*prime[j];mark[t]=1;
if(i%prime[j]==0) {mu[t]=0;break;}
mu[t]=-mu[i];
}
}
}
ll solve(ll n)
{
ll ans=0;
for(ll d=1;d*d<=n;d++)
{
ll sum=0;
for(ll D=1;D*D*D<=n/(d*d);D++) for(ll i=D;i*i<=n/(d*d*D);i++)
{
ll tmp=n/(d*d*D*i);
ll a=tmp-i,b=(tmp>=i);
if(D==i) sum+=b+a*3;
else sum+=b*3+a*6;
}
ans=ans+sum*mu[d];
}
return ans;
}
void main()
{
pre();
ll l=qread(),r=qread();
write((solve(r)-solve(l-1)+r-l+1)/2);
}
};
signed main()
{
srand(time(0));
mine::main();
}

本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
本文地址:http://zory.ink/posts/b91b.html
转载请注明出处,谢谢!