2022. 2. 8. 17:46ㆍPS/백준
위 문제에서 구하고자 하는 것은 다음과 같다.
a∑i=1b∑j=1c∑k=1τ(ijk)
필요한 이론을 증명하고 문제를 해결하자.
Theorm 1. τ(ij)=∑x|i∑y|j[x⊥y]
Lemma 1.
n=k∏i=0paiit (pi∤
일 때 다음은 n의 약수 중 p_{i}들의 배수의 개수이다.
\prod_{i=0}^{k} a_{i} \tau(t)
i=p^{a}s(p \nmid s),\ j=p^{b}t(p \nmid t)라 가정하자.
\tau(ij)=(a+b+1)\tau(st)
s, t가 서로소가 아니므로 위 과정을 반복해주자.
\tau(ij)=(a_{0}+b_{0}+1)(a_{i}+b_{i}+1)\tau(s_{1}t_{1})=\prod_{i=0}^{k} (a_{i}+b_{i}+1) \tau(s_{k})\tau(t_{k})
\gcd(s_{k},t_{k})=1이다. 마찬가지 방법으로 \tau(i), \tau(j)를 전개하자.
\tau(i)=\prod_{i=0}^{k} (a_{i}+1)\ \tau(s_{k})
\tau(j)=\prod_{i=0}^{k} (b_{i}+1)\ \tau(t_{k})
\tau(i)\tau(j)=\prod_{i=0}^{k} (a_{i}b_{i}+a_{i}+b_{i}+1)\ \tau(s_{k})\tau(t_{k})
\tau(ij)는 \tau(i)\tau(j)에서 a_{i}b_{i}라는 항이 빠진 형태이다. 이것은 i, j의 약수를 각각 x, y라 했을 때 x, y를 동시에 나누는 소수 p가 존재하는 x, y 쌍의 개수를 약수의 곱에서 제외시켜야 함을 의미한다. 즉, 다음과 같이 쓸 수 있다.
보충 설명(클릭하세요)
a_{i}\tau(s_{k})b_{i}\tau(t_{k})이고 이 항이 사라진 것이므로 Lemma 1에 의해 동시에 p_{i}으로 나누어 떨어지는 약수가 제외됨을 확인할 수 있다.
\sum_{x|i} \sum_{y|j} 1 - \sum_{x|i} \sum_{y|j}[\gcd(x,y)>1]
\sum_{x|i} \sum_{y|j} [\gcd(x,y)=1] = \sum_{x|i} \sum_{y|j} [x \perp y]
위 과정은 i, j 2개인 경우를 진행했다. 3개인 경우는 위의 경우에서 i 또는 j를 더 쪼개면 된다.
\tau(ijk)=\sum_{x|i} \sum_{y|j} \sum_{z|k} [x \perp y] [y \perp z] [z \perp x]
가장 처음의 식을 다음과 같이 변형한다.
\sum_{i=1}^{a} \sum_{j=1}^{b} \sum_{k=1}^{c} \sum_{x|i} \sum_{y|j} \sum_{z|k} [x \perp y] [y \perp z] [z \perp x]
순서를 바꾼다.
\sum_{x=1}^{a} \sum_{y=1}^{b} \sum_{z=1}^{c} \left[a/x\right]\left[b/y\right]\left[c/z\right] [x \perp y] [y \perp z] [z \perp x]
\sum_{x=1}^{a} \left[a/x\right] \sum_{y=1}^{b} \left[b/y\right] [x \perp y] \sum_{z=1}^{c} \left[c/z\right] [x \perp z] \sum_{d|y,z} \mu(d)
y=dp, z=dq라 두자.
\sum_{x=1}^{a} \left[a/x\right] \sum_{d=1}^{\min(b,c)} \mu(d) [x \perp d] \sum_{p=1}^{\left[b/d\right]} \left[b/dp\right] [x \perp p] \sum_{q=1}^{\left[c/d\right]} \left[c/dq\right] [x \perp q]
W(s, t)=\sum_{i=1}^{s} \left[s/i\right] [t \perp i]
라 정의한다. 다시 표현하면
\sum_{x=1}^{a} \left[a/x\right] \sum_{d=1}^{\min(b,c)} \mu(d) [x \perp d] W(\left[b/d\right], x) W(\left[c/d\right], x)
[x \perp y]의 누적합을 전처리 한다면 W는 O(\sqrt{s})안에 계산할 수 있다. \mu(y) [x \perp y]의 누적합을 전처리 한다면 \sum_{d=1}^{\min(b,c)}를 O(\sqrt{n})으로 계산할 수 있다. 따라서 전체 시간 복잡도는 O(n^{2})이다.
이것을 구현한 코드이다.
코드 보기
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
|
#include<stdio.h>
typedef long long ll;
#define sz 2001
ll cop[sz][sz];
ll pre_cop[sz][sz];
ll mu_cop[sz][sz];
ll mu[sz];
ll mod=1<<30;
ll sp[sz];
ll prime[sz],pt;
ll pre_bc[sz];
ll min(ll a,ll b){
return a>b?b:a;
}
ll W(ll s,ll t){
ll i,j,sum=0;
for(i=1;i<=s;i=j+1){
j=s/(s/i);
sum+=s/i*(pre_cop[t][j]-pre_cop[t][i-1])%mod;
sum%=mod;
}
return sum;
}
int main(){
ll i,j,k;
for(i=1;i<sz;i++){
for(j=1;j<sz;j++) cop[i][j]=1;
}
for(i=2;i<sz;i++){
ll h=i;
for(j=2;j*j<=h;j++){
if(h%j==0){
for(k=j;k<sz;k+=j){
cop[i][k]=0;
}
while(h%j==0) h/=j;
}
}
if(h-1){
for(j=h;j<sz;j+=h) cop[i][j]=0;
}
for(j=1;j<sz;j++) pre_cop[i][j]=cop[i][j]+pre_cop[i][j-1];
}
for(i=1;i<sz;i++){
pre_cop[1][i]=cop[1][i]+pre_cop[1][i-1];
}
mu[1]=1;
for(i=2;i<sz;i++){
if(!sp[i]){
prime[pt++]=i;
mu[i]=-1;
}
for(j=0;j<pt;j++){
if(i*prime[j]>sz) break;
sp[i*prime[j]]=1;
if(i%prime[j]==0) break;
mu[i*prime[j]]=mu[i]*mu[prime[j]];
}
}
for(i=1;i<sz;i++){
for(j=1;j<sz;j++){
mu_cop[i][j]=mu[j]*cop[i][j]+mu_cop[i][j-1];
}
}
ll a,b,c,sum=0;
scanf("%lld %lld %lld",&a,&b,&c);
for(i=1;i<=min(b,c);i=pre_bc[i]+1){
pre_bc[i]=min(b/(b/i),c/(c/i));
}
for(i=1;i<=a;i++){
ll s=0;
for(j=1;j<=min(b,c);j=k+1){
k=pre_bc[j];
s+=W(b/j,i)*W(c/j,i)%mod*(mu_cop[i][k]-mu_cop[i][j-1])%mod;
s%=mod;
}
sum=(sum+s*(a/i)%mod)%mod;
}
printf("%lld",sum);
}
|
cs |
'PS > 백준' 카테고리의 다른 글
[BOJ 17105] 골드바흐 트리플 (0) | 2022.03.04 |
---|---|
[BOJ 16808] Identity Function (0) | 2022.02.14 |
[BOJ 18496] Euclid's Algorithm (0) | 2022.01.16 |
64일 스트릭!! (0) | 2021.12.20 |
[BOJ 10438] 페리 수열의 합 (0) | 2021.11.20 |