00003:GCD depth
-
总时间限制:
- 5000ms 内存限制:
- 65536kB
-
描述
-
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
-
-
四个数 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。 主要是区间的读取边界太难处理了,代码比较丑。
-
-
-
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> using namespace std; int gcd( int a, int b ) { if( b== 0 ) { return 0; } else return gcd( b, a% b )+ 1; } int rec[200005];//储存每一个的深度 int main() { int N, M, s, e; while( scanf( "%d %d %d %d", &N, &M, &s, &e )!= EOF ) { int base= 0, cnt= 0, beg, end; //处理边界 if( N== 0 ) { if( M== 1 ) { int k= 1; if( s== 0 ) { k= 0; } cnt= e- s+ k; } else if( M== 0 ) { int k= 0; if( s== 0 ) { k= 1; } cnt= k; } printf( "%d\n", cnt ); continue; } //处理边界 for( int i= 0; i< N; i++ ) { rec[i]= gcd( N, i ); if( rec[i]+ 2== M ) { base++; } } if( s>= N ) { beg= ( int )ceil( 1.0* s/ N ); end= ( int )floor( 1.0* e/ N ); for( int i= s; i< beg* N; ++i ) { if( rec[i% N]+ 2== M ) { cnt++; } } for( int i= end* N; i<= e; ++i ) { if( i!= N ) { if( rec[i% N]+ 2== M ) { cnt++; } } } cnt+= base* ( end- beg ); if( s== N ) { if( rec[0]+ 1== M ) { cnt++; } else if( rec[0]+ 2== M ) { cnt--; } } } else if( e>= N ) { end= ( int )floor( 1.0* e/ N ); for( int i= s; i< N; ++i ) { if( rec[i]== M ) { cnt++; } } for( int i= end* N; i<= e; ++i ) { if( i!= N ) { if( rec[i% N]+ 2== M ) { cnt++; } } } cnt+= base* ( end- 1 ); if( rec[0]+ 1== M ) { cnt++; } else if( rec[0]+ 2== M ) { cnt--; } } else { for( int i= s; i<= e; ++i ) { if( rec[i]== M ) { cnt++; } } } printf( "%d\n", cnt ); } return 0; }