标签:
Description
Input
Output
Sample Input
2 1 3 1 5 1 1 11014 1 14409 9
Sample Output
Case 1: 9 Case 2: 736427
Hint
For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
题目大意:求1到b内x,1到d内y,gcd(x,y)= k 的对数,二元组无序,要求不重复
x和y的最大公约数都是k,也就是说x,y都是k的倍数,b /= k , d /= k 得到新的区间,需要找到新区间的中互质的对数,要求不重复,所以使大的数为b,小的数为d ,从1到b遍历-->i,当i小于等于d时,ans加上i的欧拉函数值,当i大于d时,计算1到d中与i互质的个数,累加得到最后的结果。
为防止超时,要将欧拉函数值提前处理好,还有将一个数的分解也要预处理。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define LL __int64 #define maxn 110000 LL euler[maxn] ;//记录1到i的欧拉函数和 LL p[maxn][30] , p_num[maxn] ; //质因子个数 void sieve() { LL i , j ; memset(p_num,0,sizeof(p_num)) ; memset(p,0,sizeof(p)) ; memset(euler,0,sizeof(euler)) ; for(i = 1 ; i < maxn ; i++) euler[i] = i ; for(i = 2 ; i < maxn ; i++) { if( euler[i] == i ) { euler[i] = i-1 ;//是=素数 p[i][p_num[i]++] = i ; for(j = 2*i ; j < maxn ; j += i) { p[j][ p_num[j]++ ] = i ; euler[j] = euler[j] * (i-1) / i ; } } euler[i] += euler[i-1] ; } } int cop(int n,int m) { int i , j , num , temp , x = 1<<p_num[m] ; int ans = 0 ; for(i = 1 ; i < x ; i++) { for(j = 0 , num = 0 , temp = 1 ; j < p_num[m] ; j++) { if( (1<<j) & i ) { num++ ; temp *= p[m][j] ; } } if( num % 2 ) ans += n/temp ; else ans -= n/temp ; } return n-ans ; } int max(int a,int b) { return a > b ? a : b ; } int min(int a,int b) { return a > b ? b : a ; } LL f(int a,int b) { int n = max(a,b) , m = min(a,b) ; LL num = euler[m] ; for(int i = m+1 ; i <= n ; i++) num += cop(m,i) ; return num ; } int main() { int a , b , c , d , k ; int t , tt ; sieve() ; scanf("%d", &t) ; for(tt = 1 ; tt <= t ; tt++) { scanf("%d %d %d %d %d", &a, &b, &c, &d, &k) ; if(k == 0 || k > b || k > d) { printf("Case %d: 0\n", tt); continue ; } printf("Case %d: %I64d\n", tt, f(b/k,d/k) ); } return 0; }
标签:
原文地址:http://blog.csdn.net/winddreams/article/details/42530319