这个题要用容斥定理,求出x与y互质的对数,然后x与y同时乘以k,如果x与y都在范围之内,则这一对符合条件;
这里的处理方法就是对b与d缩小k倍,寻找里面的互质的数的对数,我们在扩大k倍,就可以解决,上面存在的问题;


#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<set> #include<map> #include<cstring> #include<vector> #include<string> #define LL long long using namespace std; int prime[10000],cnt; class Node { public: int num[20]; int cnt; }node[100024]; void Prime( ) { bool hash[50025] = {0}; int t = ( int )sqrt( 100000.0 ) + 1; for( int i = 3 ; i <= t ; i += 2 ) { if( hash[i>>1]==false ) { int x = i << 1; for( int j = i * i ; j <=100000 ; j += x ) hash[j>>1] = true; } } cnt = 0; prime[cnt++] = 2; for( int i = 1; i <= 50000 ; i ++ ) { if( hash[i]==false ) { prime[cnt++] = ( i << 1 ) + 1; } } for( int i = 1 ; i <= 100000; i ++ )//求质因子 { t = i; node[i].cnt = 0; for( int j = 0; j < cnt ; j ++ ) { if( t < prime[j] ) break; if( t % prime[j] == 0 ) { node[i].num[node[i].cnt++] = prime[j]; while( t % prime[j] == 0 ) t /= prime[j]; } } } } LL DFS( int d , int m , int t )//容斥 { LL ans = 0; for( int i = t ; i < node[m].cnt ; i ++ ) { ans += (LL)d/node[m].num[i] - DFS( d/node[m].num[i] , m , i + 1 ); } return ans; } int main( ) { Prime(); int a,b,c,d,T,k; while( scanf( "%d",&T )==1 ) { for( int l = 1 ; l <= T ; l ++ ) { LL ans = 0; scanf( "%d %d %d %d %d",&a,&b,&c,&d,&k ); printf( "Case %d: ",l ); if( k == 0 ) printf( "0\n" ); else { if( b >= k && d >= k ) ans = 1; //把b,d缩小k倍,求所有范围内的互质的数,在扩大k倍之后,一定在原先的范围之内 b /= k; d /= k; if( b > d ) swap( b ,d ); for( int i = 1 ; i <= b ; i ++ ) { int t = d - i ; if( t <= 0 ) break; ans +=(LL) t - DFS( t , i , 0 ); } printf( "%I64d\n",ans ); } } } //system( "pause" ); return 0; }