标签:
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