Description
给定一个正整数 N ( N < = 2 31 − 1 ) N(N<=2^{31}-1) N(N<=231−1)
求 a n s 1 = ∑ i = 1 N ϕ ( i ) , a n s 2 = ∑ i = 1 N μ ( i ) ans1=\sum_{i=1}^N\phi(i),ans2=\sum_{i=1}^N\mu(i) ans1=∑i=1Nϕ(i),ans2=∑i=1Nμ(i),多组询问
Input
一共T+1行
第1行为数据组数T(T<=10)
第2~T+1行每行一个非负整数N,代表一组询问
Output
一共T行,每行两个用空格分隔的数ans1,ans2
Sample Input
6
1
2
8
13
30
2333
Sample Output
1 1
2 0
22 -2
58 -3
278 -3
1655470 2
杜教筛模板题
入门见:https://blog.csdn.net/a1035719430/article/details/85208451
关于狄利克雷卷积:https://blog.csdn.net/a1035719430/article/details/84958962
由上面这个博文我们可以知道
μ
∗
I
=
e
,
ϕ
∗
I
=
ε
\mu*I=e,\phi*I=\varepsilon
μ∗I=e,ϕ∗I=ε
e
e
e的前缀和就是
1
1
1,
ε
\varepsilon
ε的前缀和是
n
∗
(
n
+
1
)
2
\frac{n*(n+1)}{2}
2n∗(n+1)
然后直接做杜教筛就行了
注意这题的坑点,
n
+
1
n+1
n+1正好爆了
i
n
t
int
int…
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x],y = e[i].y;i;i = e[i].n,y = e[i].y)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
#define fr first
#define se second
int rd()
{
int num = 0;char c = getchar();bool flag = true;
while(c < '0'||c > '9') {if(c == '-') flag = false;c = getchar();}
while(c >= '0' && c <= '9') num = num*10+c-48,c = getchar();
if(flag) return num;else return -num;
}
const int N = 2e6;
unordered_map<int,ll>Phi,Miu;
int prime[N+10],v[N+10];
ll phi[N+10],miu[N+10];
inline ll get(int i,int j)
{
return 1ll*(i+j)*(j-i+1)/2;
}
int cas = 0;
Pll solve(int n)
{
if(n<=N) return mp(phi[n],miu[n]);
if(Miu.find(n) != Miu.end()) return mp(Phi[n],Miu[n]);
Pll now = mp(1ll*n*(1ll*n+1)/2,1);int i = 2;
while(i <= n)
{
int j = n/(n/i);
Pll to = solve(n/i);
now.fr -= 1ll*(j-i+1)*to.fr; now.se -= 1ll*(j-i+1)*to.se;
if(j == n) break;
i = j+1;
}
Phi[n] = now.fr; Miu[n] = now.se;
return mp(Phi[n],Miu[n]);
}
void pre()
{
miu[1] = 1;phi[1] = 1;
rep(i,2,N)
{
if(!phi[i]) prime[++prime[0]] = i,phi[i] = i-1,v[i] = i,miu[i] = -1;
rep(j,1,prime[0])
{
if(i*prime[j]>N || v[i] < prime[j]) break;
v[i*prime[j]] = prime[j];
phi[i*prime[j]] = phi[i] * (i%prime[j]?prime[j]-1:prime[j]);
if(i%prime[j] == 0) break;
miu[i*prime[j]] = -miu[i];
}
}
rep(i,2,N) miu[i] += miu[i-1],phi[i] += phi[i-1];
}
int main()
{
pre();
int T = rd();
while(T--)
{
int x = rd();
Pll now = solve(x);
printf("%lld %lld\n",now.fr,now.se);
}
return 0;
}