描述
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 }