hdu 1695
题目大意:
求
xϵ(1,n)
,
yϵ(1,m)
,
gcd(x,y)=k
的
x,y
的对数;
思路:
令
n<m
xϵ(1,n)
,
yϵ(1,n)
,
num1gcd(x,y)=φ(nk)
;
xϵ(1,n)
,
yϵ(n+1,m)
, 因式分解
x
,
ans=num1+num2
;
#include <iostream>
#include <cstdio>
#define LL __int64
#define N 100002
using namespace std;
LL euler[N];
struct Num
{
int prim[20];
int num;
}c[N];
void init_Euler() //euler打表+素数分解
{
for (int i = 0; i < N; i++)
{
c[i].num = 0;
euler[i] = 0;
}
euler[1] = 1;
for (int i = 2; i < N; i++)
{
if (!euler[i])
{
for (int j = i; j < N; j += i)
{
if (!euler[j])
{
euler[j] = j;
}
euler[j] = euler[j] / i * (i - 1);
c[j].prim[c[j].num] = i;
c[j].num++;
}
}
euler[i] += euler[i-1];
}
}
LL get_ans(int pi, LL n) //枚举版
{
LL ans = 0;
for (int i = 1; i < (1 << c[pi].num); i++)
{
int tmp = 1, flag = 0;
for (int j = 0; j < c[pi].num; j++)
{
if (i & (1 << j))
{
flag++;
tmp *= c[pi].prim[j];
}
}
if (flag & 1)
{
ans += n / tmp;
}
else
{
ans -= n / tmp;
}
}
return ans;
}
LL dfs(int index, LL b, LL n) //递归版
{
LL ans = 0, t;
for (int i = index; i < c[n].num; i++)
{
t = b / c[n].prim[i];
ans += t - dfs(i + 1, t, n);
}
return ans;
}
int main()
{
int T;
init_Euler();
while (~scanf("%d", &T))
{
for (int cas = 1; cas <= T; cas++)
{
int a, c;
LL b, d, k;
scanf("%d%I64d%d%I64d%I64d", &a, &b, &c, &d, &k);
if (k == 0)
{
printf("Case %d: 0\n", cas);
continue;
}
if (b > d)
{
swap(b, d);
}
LL tmp = b / k;
LL ans = euler[tmp];
if (b == d)
{
printf("Case %d: %I64d\n", cas, ans);
continue;
}
b /= k;
d /= k;
for (int i = b + 1; i <= d; i++)
{
// ans += b - get_ans(i, b);
ans += b - dfs(0, b, i);
}
printf("Case %d: %I64d\n", cas, ans);
}
}
return 0;
}