Skip to content

Commit 2863a6b

Browse files
authored
Merge pull request #203 from dwivediprashant/code/day-2-que3
Code(JAVA) : Solved que-3 of day-2
2 parents 7fc2770 + 61f35f7 commit 2863a6b

1 file changed

Lines changed: 156 additions & 0 deletions

File tree

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/*
2+
Problem Statement:
3+
You are given an integer N.
4+
5+
Define the following summation:
6+
7+
∑_{i=1..N} ∑_{j=1..N} ∑_{k=1..i} ∑_{l=1..j}
8+
gcd(k, i) × gcd(l, j) × gcd(i, j)
9+
10+
Your task is to compute the value of this summation modulo 1000000007.
11+
12+
---------------------------------------
13+
Observations:
14+
1. The inner sums:
15+
∑_{k=1..i} gcd(k, i)
16+
depend only on i, not on j.
17+
18+
2. Let:
19+
S(n) = ∑_{k=1..n} gcd(k, n)
20+
21+
It is a known number-theoretic identity that:
22+
S(n) = ∑_{d | n} φ(d) × (n / d)
23+
24+
3. Using the identity:
25+
gcd(i, j) = ∑_{d | i and d | j} φ(d)
26+
27+
we can rearrange the original 4D summation
28+
into a divisor-based formulation.
29+
30+
---------------------------------------
31+
Final Reduced Formula:
32+
The entire expression becomes:
33+
34+
∑_{d=1..N} φ(d) × ( ∑_{m ≤ N, d | m} S(m) )²
35+
36+
---------------------------------------
37+
Approach:
38+
1. Precompute Euler's Totient Function φ(i) for all i ≤ N using sieve.
39+
2. Compute S(n) for all n using divisor enumeration.
40+
3. For each d, compute F(d) = sum of S(m) where d divides m.
41+
4. Accumulate the answer using:
42+
ans += φ(d) × F(d)²
43+
44+
---------------------------------------
45+
Time Complexity:
46+
- Totient sieve: O(N log log N)
47+
- Computing S(n): O(N log N)
48+
- Computing F(d): O(N log N)
49+
50+
Overall: O(N log N)
51+
52+
---------------------------------------
53+
Space Complexity:
54+
O(N)
55+
56+
---------------------------------------
57+
Constraints:
58+
1 ≤ N ≤ 10⁶
59+
60+
---------------------------------------
61+
*/
62+
/*------------------Problem submission link -------------------------
63+
https://www.codechef.com/viewsolution/1221660384
64+
*/
65+
66+
import java.io.*;
67+
68+
public class Solution3 {
69+
70+
static final long MOD = 1_000_000_007L;
71+
72+
public static void main(String[] args) throws Exception {
73+
74+
FastScanner fs = new FastScanner(System.in);
75+
int N = fs.nextInt();
76+
77+
/* Step 1: Compute Euler Totient φ for all numbers */
78+
int[] phi = new int[N + 1];
79+
for (int i = 1; i <= N; i++) phi[i] = i;
80+
81+
for (int i = 2; i <= N; i++) {
82+
if (phi[i] == i) { // i is prime
83+
for (int j = i; j <= N; j += i) {
84+
phi[j] -= phi[j] / i;
85+
}
86+
}
87+
}
88+
89+
/* Step 2: Compute S(n) = sum_{k=1..n} gcd(k, n) */
90+
long[] S = new long[N + 1];
91+
for (int d = 1; d <= N; d++) {
92+
for (int m = d; m <= N; m += d) {
93+
S[m] += (long) phi[d] * (m / d);
94+
}
95+
}
96+
97+
/* Step 3: Compute F(d) = sum of S(m) where d divides m */
98+
long[] F = new long[N + 1];
99+
for (int d = 1; d <= N; d++) {
100+
long sum = 0;
101+
for (int m = d; m <= N; m += d) {
102+
sum += S[m];
103+
// prevent overflow in extreme cases
104+
if (sum >= Long.MAX_VALUE / 4) sum %= MOD;
105+
}
106+
F[d] = sum % MOD;
107+
}
108+
109+
/* Step 4: Final accumulation */
110+
long ans = 0;
111+
for (int d = 1; d <= N; d++) {
112+
long x = F[d];
113+
long sq = (x * x) % MOD;
114+
ans = (ans + phi[d] * sq) % MOD;
115+
}
116+
117+
System.out.println(ans);
118+
}
119+
120+
/* Fast input reader for large constraints */
121+
static class FastScanner {
122+
private final byte[] buffer = new byte[1 << 16];
123+
private int ptr = 0, len = 0;
124+
private final InputStream in;
125+
126+
FastScanner(InputStream in) {
127+
this.in = in;
128+
}
129+
130+
private int readByte() throws IOException {
131+
if (ptr >= len) {
132+
len = in.read(buffer);
133+
ptr = 0;
134+
if (len <= 0) return -1;
135+
}
136+
return buffer[ptr++];
137+
}
138+
139+
int nextInt() throws IOException {
140+
int c, sign = 1, val = 0;
141+
do {
142+
c = readByte();
143+
} while (c <= ' ');
144+
145+
if (c == '-') {
146+
sign = -1;
147+
c = readByte();
148+
}
149+
while (c > ' ') {
150+
val = val * 10 + (c - '0');
151+
c = readByte();
152+
}
153+
return val * sign;
154+
}
155+
}
156+
}

0 commit comments

Comments
 (0)