Skip to main content

Crimson Triples

Madhav
EditReport

Description:​

After summoning the next boss — The Brain of Cthulhu, you noticed that it surrounds itself with nn eyes, numbered from 11 to nn. In one attack, The Brain of Cthulhu chooses a triple of eyes (not necessarily distinct) with numbers (a,b,c)(a,b,c). The triple of eyes is called crimson if and only if the following property holds:

gcd⁥(lcm⁥(a,b),lcm⁥(b,c))=gcd⁥(a,c)\gcd(\operatorname{lcm}(a,b),\operatorname{lcm}(b,c))=\gcd(a,c)

To defeat the boss, you want to know how many ways The Brain of Cthulhu can choose a crimson triple of eyes. The triples of eyes (a1,b1,c1)(a_1,b_1,c_1) and (a2,b2,c2)(a_2,b_2,c_2) are considered different if a1≠a2a_1 \neq a_2, or b1≠b2b_1 \neq b_2, or c1≠c2c_1 \neq c_2.

Input Each test contains multiple test cases. The first line contains the number of test cases tt (1≤t≤10001 \le t \le 1000). The description of the test cases follows. The only line of each test case contains one integer nn (1≤n≤2⋅1051 \le n \le 2 \cdot 10^5) — the number of eyes of The Brain of Cthulhu. It is guaranteed that the sum of nn across all test cases does not exceed 2⋅1052 \cdot 10^5.

Output For each test case, output one integer — the number of ways to choose a crimson triple of eyes.


Approaches:​

1. Math and Number Theory Observation​

To solve this problem efficiently, we need to simplify the condition gcd⁥(lcm⁥(a,b),lcm⁥(b,c))=gcd⁥(a,c)\gcd(\operatorname{lcm}(a,b),\operatorname{lcm}(b,c)) = \gcd(a,c).

  1. Prime Factorization Analysis: Let's look at the exponent of a specific prime pp in the prime factorization of a,b,a, b, and cc. Let these exponents be x,y,x, y, and zz respectively.
    • The exponent of pp in lcm⁥(a,b)\operatorname{lcm}(a,b) is max⁥(x,y)\max(x, y).
    • The exponent of pp in lcm⁥(b,c)\operatorname{lcm}(b,c) is max⁥(y,z)\max(y, z).
    • The exponent of pp on the left-hand side (LHS) of our equation is min⁥(max⁥(x,y),max⁥(y,z))\min(\max(x, y), \max(y, z)).
    • The exponent of pp on the right-hand side (RHS) of our equation is min⁥(x,z)\min(x, z).
  2. Deriving the Requirement: We need min⁥(max⁥(x,y),max⁥(y,z))=min⁥(x,z)\min(\max(x, y), \max(y, z)) = \min(x, z) for all primes pp.
    • If you test the possible orderings of x,y,x, y, and zz, you will find this equality only holds if y≤xy \le x and y≤zy \le z.
    • This means the exponent of any prime pp in bb must be less than or equal to its exponent in both aa and cc.
    • In number theory terms, this simply means bb must divide aa and bb must divide cc.
  3. Counting the Triples: Now the problem is reduced to finding the number of pairs (a,c)(a, c) such that both are multiples of bb, for every possible bb from 11 to nn.
    • For a fixed bb, there are exactly ⌊n/b⌋\lfloor n/b \rfloor multiples of bb in the range [1,n][1, n].
    • Since aa and cc are chosen independently from these multiples, there are ⌊n/b⌋×⌊n/b⌋\lfloor n/b \rfloor \times \lfloor n/b \rfloor valid pairs for a given bb.
    • We just need to sum ⌊n/b⌋2\lfloor n/b \rfloor^2 for all bb from 11 to nn.

Complexity​

  • Time Complexity: O(n)O(n) per testcase. Since the sum of nn across all test cases is ≤2⋅105\le 2 \cdot 10^5, the overall time complexity is O(N)O(N) which easily passes within the time limit.
  • Space Complexity: O(1)O(1) as we only need a few variables to store the sum.

Solutions:​

C++​

#include <iostream>

using namespace std;

void solve() {
int n;
cin >> n;
long long res = 0;

// Sum (n / b)^2 for all 1 <= b <= n
for (int b = 1; b <= n; b++) {
long long multiples = n / b;
res += multiples * multiples;
}

cout << res << "\n";
}

int main() {
// Fast I/O
ios_base::sync_with_stdio(false);
cin.tie(NULL);

int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}

Java​

import java.util.Scanner;

public class Solution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
if (scanner.hasNextInt()) {
int t = scanner.nextInt();
while (t-- > 0) {
solve(scanner);
}
}
scanner.close();
}

private static void solve(Scanner scanner) {
int n = scanner.nextInt();
long res = 0;

// Sum (n / b)^2 for all 1 <= b <= n
for (int b = 1; b <= n; b++) {
long multiples = n / b;
res += multiples * multiples;
}

System.out.println(res);
}
}

Python​

import sys

def solve():
input_data = sys.stdin.read().split()
if not input_data:
return

t = int(input_data[0])

for i in range(1, t + 1):
n = int(input_data[i])
res = 0

# Sum (n / b)^2 for all 1 <= b <= n
for b in range(1, n + 1):
multiples = n // b
res += multiples * multiples

print(res)

if __name__ == "__main__":
solve()

JavaScript​

const fs = require('fs');

function main() {
const input = fs.readFileSync(0, 'utf-8').trim().split(/\s+/);
if (input.length === 0 || input[0] === '') return;

let t = parseInt(input[0], 10);
let index = 1;

for (let i = 0; i < t; i++) {
let n = parseInt(input[index++], 10);
let res = 0; // Number max safe integer is ~9e15, max answer is ~3.2e10, so safe.

// Sum (n / b)^2 for all 1 <= b <= n
for (let b = 1; b <= n; b++) {
let multiples = Math.floor(n / b);
res += multiples * multiples;
}

console.log(res);
}
}

main();
Telemetry Integration

Completed working through this block? Sync progress to workspace.