Stern-Brocot Tree
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Problem Description
vcr9wdBGoaM8YnI+CqGhoaHP1tTax+vE+rHgs8y8xsvjtdpu0NC1xMr9wdBGtcS49sr9oaM8YnI+CgoKIAo8YnI+CgpJbnB1dAoKoaGhocrkyOuw/LqstuDX6bLiytTTw8D9o6zDv9fpyuTI68r9vt3Kx9K7uPbV/dX7yv1uo6huPD0xMDAwMDAwo6mhowoKIAo8YnI+CgpPdXRwdXQKCqGhoaG21NPaw7/X6bXEsuLK1Mr9vt1uo6zH68rks/a12m7Q0LXEyv3B0Ea1xLj2yv2howoKIAo8YnI+CgpTYW1wbGUgSW5wdXQKCjxwcmUgY2xhc3M9"brush:java;">1 2 4 6
3 5 13 25仔细看图可以发现:对于每一行都可以看成是关于1/1对称的两部分,所以只需求出1/1左边的个数就可求出这一行的个数。而左边全部都是真分数,分母为x的真分数的个数就是x的欧拉函数值。n最大为1000000,所以可以递推打表。
#includeconst int N = 1000001; int e[N]; __int64 a[N], res = 0; void euler() { for(int i = 2; i < N; i++) e[i] = 0; e[1] = 1; for(int i = 2; i < N; i++) if(!e[i]) { for(int j = i; j < N; j += i) { if(!e[j]) e[j] = j; e[j] = e[j] / i * (i-1); } } } int main() { int i, n; euler(); for(i = 1; i < N; i++) { res += e[i]; a[i] = res * 2 + 1; } while(~scanf("%d", &n)) printf("%I64d\n", a[n]); return 0; }