HUT-1602 GCD depth

1602: GCD depth

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 24  Solved: 3
[Submit][Status][Web Board]

Description

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.

Input

  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.

Output

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

Sample Input

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

Sample Output

2 1 0

 

  四个数 N, M, S, E, 求 GCD_depth( N, i ) == M 的个数,其中 i 属于 [s, e]。

  思路:该题我们只要将 i 属于 [0 - N) 的GCD_depth计算出来,然后大于N的数就用 GCD_depth( N, i% N ) + 2 == M 去统计了,自己推一下就能明白为什么了。 注意当这个数等于N的时候比较特殊,这时候是加1而不是加 2。 主要是区间的读取边界太难处理了,代码比较丑。

  

  1 #include <cstdio>
2 #include <cstring>
3 #include <cstdlib>
4 #include <cmath>
5 using namespace std;
6
7 int gcd( int a, int b )
8 {
9 if( b== 0 )
10 {
11 return 0;
12 }
13 else return gcd( b, a% b )+ 1;
14 }
15
16 int rec[200005];
17
18 int main()
19 {
20 int N, M, s, e;
21 while( scanf( "%d %d %d %d", &N, &M, &s, &e )!= EOF )
22 {
23 int base= 0, cnt= 0, beg, end;
24 if( N== 0 )
25 {
26 if( M== 1 )
27 {
28 int k= 1;
29 if( s== 0 )
30 {
31 k= 0;
32 }
33 cnt= e- s+ k;
34 }
35 else if( M== 0 )
36 {
37 int k= 0;
38 if( s== 0 )
39 {
40 k= 1;
41 }
42 cnt= k;
43 }
44 printf( "%d\n", cnt );
45 continue;
46 }
47 for( int i= 0; i< N; ++i )
48 {
49 rec[i]= gcd( N, i );
50 if( rec[i]+ 2== M )
51 {
52 base++;
53 }
54 }
55 if( s>= N )
56 {
57 beg= ( int )ceil( 1.0* s/ N ), end= ( int )floor( 1.0* e/ N );
58 for( int i= s; i< beg* N; ++i )
59 {
60 if( rec[i% N]+ 2== M )
61 {
62 cnt++;
63 }
64 }
65 for( int i= end* N; i<= e; ++i )
66 {
67 if( i!= N )
68 {
69 if( rec[i% N]+ 2== M )
70 {
71 cnt++;
72 }
73 }
74 }
75 cnt+= base* ( end- beg );
76 if( s== N )
77 {
78 if( rec[0]+ 1== M )
79 {
80 cnt++;
81 }
82 else if( rec[0]+ 2== M )
83 {
84 cnt--;
85 }
86 }
87 }
88 else if( e>= N )
89 {
90 end= ( int )floor( 1.0* e/ N );
91 for( int i= s; i< N; ++i )
92 {
93 if( rec[i]== M )
94 {
95 cnt++;
96 }
97 }
98 for( int i= end* N; i<= e; ++i )
99 {
100 if( i!= N )
101 {
102 if( rec[i% N]+ 2== M )
103 {
104 cnt++;
105 }
106 }
107 }
108 cnt+= base* ( end- 1 );
109 if( rec[0]+ 1== M )
110 {
111 cnt++;
112 }
113 else if( rec[0]+ 2== M )
114 {
115 cnt--;
116 }
117 }
118 else
119 {
120 for( int i= s; i<= e; ++i )
121 {
122 if( rec[i]== M )
123 {
124 cnt++;
125 }
126 }
127 }
128 printf( "%d\n", cnt );
129 }
130 }

  

  

posted @ 2011-08-17 17:25  沐阳  阅读(471)  评论(0编辑  收藏  举报