标签:
Description
Input
Output
Sample Input
2 1 10 2 3 15 5
Sample Output
Case #1: 5 Case #2: 10
Hint
In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}.
题目大意: 计算a到b内,与n互质的个数
分别统计1到a-1中,和1到b中与n互质的数,在相减,求1到m中与n互质的数,先求1到m中与n不互质的数的个数。
求出n分解后的质数个数,用二进制数表示第i个质数的选和不选,得到m内包含的个数,当选了奇数个质数是,统计的结果累加,为偶数个时,减去。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define LL __int64 int prim[1000000] , vis[1000000] , cnt ; void sieve() { memset(vis,0,sizeof(vis)) ; cnt = 0 ; LL i , j ; for(i = 2 ; i <= 1000000 ; i++) { if( !vis[i] ) { prim[cnt++] = i ; for(j = i*i ; j < 1000000 ; j += i) vis[j] = 1 ; } } } LL p[1000] , p_num ; LL f(LL n,LL m) { LL k = n , temp , ans = 0 ; int i , j , num ; for(i = 0 , p_num = 0 ; i < cnt ; i++) { if( k % prim[i] == 0 ) { p[p_num++] = prim[i] ; } while( k % prim[i] == 0 ) { k /= prim[i] ; } if(k == 1) break ; } if( k > 1 ) p[p_num++] = k ; for(i = 1 ; i < (1<<p_num) ; i++) { for(j = 0 , num = 0 , temp = 1 ; j < p_num ; j++) { if( (1<<j) & i ) { temp *= p[j] ; num++ ; } } if( num % 2 ) ans += m/temp ; else ans -= m/temp ; } return ans ; } int main() { LL t , tt , a , b , n ; sieve() ; scanf("%I64d", &t) ; for(tt = 1 ; tt <= t ; tt++) { scanf("%I64d %I64d %I64d", &a, &b, &n) ; printf("Case #%I64d: %I64d\n", tt, (b-f(n,b))-(a-1-f(n,a-1)) ); } return 0; }
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42530481