Problem:
Problem F: Farey Sequence

slipは数字を眺めるのが好きである。
ファイルをダウンロードしているときの、残り時間を眺めているだけで、時間を潰せるほどである。
そんなslipが友人から面白い数列を教えられた。
その数列の定義は以下のとおりである。

一般項をFnと表わす。
Fnとは、n以下の分母を持つ0以上1以下のすべての約分された分数(既約分数)を小さな順から並べたものである。
ただし、整数0、1はそれぞれ分数0/1、1/1として扱われる。

つまりF3は、

F3 = (0/1, 1/3, 1/2, 2/3, 1/1)

のように表される。

F5であれば

F5 = (0/1, 1/5, 1/4, 1/3, 2/5, 1/2, 3/5, 2/3, 3/4, 4/5, 1/1)

と表される。

slipはこの数列にすぐにのめり込んだ。
しかしこの数列を眺めていても、なかなか特徴がつかめなかった。
特徴をつかむためにまずは各項の項数がいくつあるのか調べようと思ったが、
増え方の規則がわからず、自力で理解することを断念した。

そこで、
勝手に友人と思っているあなたに、指定した項にどれだけの項数があるのかを聞くことにした。
あなたの仕事は、与えられた項における項数を求めることである。

Input

入力は以下の形式で与えられる。

t
n1
...
ni
...
nt

t(1 ≤ t ≤ 10000)はテストケースの数である。
ni(1 ≤ ni ≤ 1000000)は与えられた項の番号である。

Output

各テストケースごとに、項数を1行に表示せよ。

Sample Input

2
3
5

Output for Sample Input

5
11

Solution in JAVA (judge verdict: Accepted)

import java.util.Arrays;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

//Farey Sequence
public class Main{

	int N = 1000000;
	boolean[] p;
	
	long gcd(long a, long b){
		return b==0?a:gcd(b, a%b);
	}

	long get(int x){
		int n = x;
		Set<Integer> set = new HashSet<Integer>();
		int div = 2;
		while(x>1){
			if(p[x]){
				set.add(x); break;
			}
			if(x%div==0){
				set.add(div);
				x/=div;
			}
			else div++;
		}
		int m = set.size();
		int[] a = new int[m];
		int id = 0;
		for(int i:set)a[id++]=i;
		long res = 0;
		for(int i=1;i<1<<m;i++){
			int num = 0;
			for(int j=i;j!=0;j>>=1)num+=j&1;
			long lcm = 1;
			for(int j=0;j<m;j++){
				if((i>>j&1)>0){
					lcm = lcm/gcd(lcm, a[j])*a[j];
					if(lcm>n)break;
				}
			}
			if(num%2==0)res-=n/lcm;
			else res+=n/lcm;
		}
		return res;
	}
	
	void run(){
		p = new boolean[N+1];
		Arrays.fill(p, true);
		p[0]=p[1]=false;
		for(int i=2;i<=N;i++)if(p[i])for(int j=i+i;j<=N;j+=i)p[j]=false;
		long[] res = new long[N+1];
		res[1] = 2;
		for(int i=2;i<=N;i++){
			res[i] = res[i-1];
			res[i]+=i-get(i);
		}
		Scanner sc = new Scanner(System.in);
		int T = sc.nextInt();
		while(T--!=0)System.out.println(res[sc.nextInt()]);
	}
	
	public static void main(String[] args) {
		new Main().run();
	}
}