TZOJ 3698 GCD depth(数学)

描述

In mathematics, the greatest common divisor (gcd), also known as the greatest common factor (gcf), or highest common factor (hcf), of two or more non-zero integers, is the largest positive integer that divides the numbers without a remainder. For example, the GCD of 8 and 12 is 4.
------ From Wikipedia
In this problem,we will introduce a new value related to GCD,which is GCD depth. To GCD depth,follow function will discribe it clearly.
    int GCD_depth( int x , int y ) {
        if ( y == 0 ) return 0;
        else return GCD_depth( y , x%y ) + 1;
    }
And we define the GCD depth of y with x is GCD_depth(x,y).For example , GCD depth of 5 with 3 is 4.You can find the GCD depth of two numbers easily ,but LH wants know that: for a number x, how many numbers meet the condition that the GCD depth with x equals to d in the interval [y0,y1]? So please help LH to find the answer quickly.

输入

There are several test cases, each test case contains four Non-negative integers x( 0 <= x <= 200000) , d( 0 <= d <= 30 ),y0 ,y1(0 <= y0 <= y1 <= 10^9),which descripted as above.
    The input will finish with the end of file.

输出

For each the case, just output a integer which represent the number of integers meeted the discripted condition.

样例输入

7 2 0 5
3 0 0 1
11 1 2 8

样例输出

2
1
0

题意

求区间[y0,y1]中与x的gcd递归次数=d的数的个数。

题解

不难想到,当y>x的时候相当于先交换了一次,再取模了一次最后变成gcd(x,y)。

可以想到应该是分块统计答案,[0,x-1]+[x,2*x-1]+....。

然后发现几种特殊情况:

1.x=y时递归次数=1。

2.y%x==0时递归次数=2。

3.当x=0时,由于分块会/0需要特殊处理。

  1.当d=0,y包含0输出1,不包含输出0。(因为y=0时递归深度一定为0)

  2.当d=1,y包含0输出y1-y0,不包含输出y1-y0+1。(同上)

  3.当d为其他值,输出0。(如果y等于0深度为0,否则深度为1)

4.大坑,需要处理x=y时y%x==0多算或多减的问题。

代码

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4 
 5     public static int GCD_depth(int x, int y) {
 6         if (y == 0) return 0;
 7         else return GCD_depth(y , x%y) + 1;
 8     }
 9 
10     public static int calculator(int[] vis, int x, int d, int r) {
11         if (r < 0) return 0;
12         int ans = 0;
13         if (x <= r && GCD_depth(x, x) == d) ans++;
14         r++;
15         int seg = r / x;
16         int l = seg * x;
17         if (seg >= 1) ans += vis[d] + (d >= 2 ? (seg - 1) * vis[d - 2] : 0);
18         if (seg >= 2 && x < r && d == 2 && GCD_depth(x, x) != d) ans--;
19         for (int i = l; i < r; i++) {
20             int dep = GCD_depth(x, i % x) + (seg == 0 ? 0 : 2);
21             if (i != x && dep == d) ans++;
22         }
23         return ans;
24     }
25 
26     public static void main(String[] args) {
27 
28         Scanner sc = new Scanner(System.in);
29         while (sc.hasNextInt()) {
30             int x = sc.nextInt();
31             int d = sc.nextInt();
32             int y0 = sc.nextInt();
33             int y1 = sc.nextInt();
34             if (x == 0) {
35                 if (d == 0) {
36                     if (y0 <= 0 && 0 <= y1) System.out.println(1);
37                     else System.out.println(0);
38                 } else if (d == 1) {
39                     if (y0 <= 0 && 0 <= y1) System.out.println(y1 - y0);
40                     else System.out.println(y1 - y0 + 1);
41                 } else System.out.println(0);
42                 continue;
43             }
44             int[] vis = new int[31];
45             for (int i = 0; i < x; i++) {
46                 int depth = GCD_depth(x, i);
47                 vis[depth]++;
48             }
49             System.out.println(calculator(vis, x, d, y1) - calculator(vis, x, d, y0 - 1));
50         }
51     }
52 
53 }

posted on 2020-02-06 23:20  大桃桃  阅读(238)  评论(0编辑  收藏  举报

导航