【欧拉函数+容斥原理】HDU 1695 GCD

[url]http://acm.hdu.edu.cn/showproblem.php?pid=1695[/url]

[size=medium][b]题意:求[a,b]和[c,d]中分别取一个数,问取到的两个数的gcd=k的对数!!其中(2,3)跟(3,2)这2种类型只算一种,视为重复[/b]

[b][color=blue]Sample Input
2
1 3 1 5 1
1 11014 1 14409 9

Sample Output
Case 1: 9
Case 2: 736427[/color][/b][/size]


#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <set>
//#include <map>
#include <queue>
#include <utility>
#include <iomanip>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
//#include <ctime>
#include <ctype.h>
using namespace std;
#define eps 1e-8
#define PI 3.14159265358979
#define inf 0x3fffffff
#define L 100005

long long e[L];
int prime[L][20], num[L]; //prime[i][j]储存i的第j个质因子,num[i]储存i的质因子个数

void Euler ()
{
int i, j;
for (i = 1; i < L; i++) //初始化
e[i] = i;
for (i = 2; i < L; i++)
{
if (e[i] == i) //只有素数才可进来
{
e[i] = i - 1;
for (j = i << 1; j < L; j += i) //求欧拉的同时求质因子
e[j] = e[j] - e[j] / i, prime[j][num[j]++] = i;
}
}
for (i = 2; i < L; i++) //递推求和
e[i] += e[i-1];
}

int dfs (int x, int b, int n) //求[1,b]中有多少个与n非互质
{
if (!b)
return 0;
int ans = 0, i;
for (i = x; i < num[n]; i++)
ans += b/prime[n][i] - dfs (i+1, b/prime[n][i], n); //容斥原理
return ans;
}

int main()
{
int t, a, b, c, d, k, cc = 1, i;
long long res;
memset (num, 0, sizeof(num));
Euler ();
scanf ("%d", &t);
while (t--)
{
scanf ("%d%d%d%d%d", &a, &b, &c, &d, &k);
printf ("Case %d: ", cc++);
if (!k) //k==0下面作为分母会出大错
{
puts ("0");
continue;
}
b /= k, d /= k; //问题的转化,转化成求gcd=1的对数
if (d < b)
d ^= b, b ^= d, d ^= b;
res = e[b]; //[1,b]和[1,b]的gcd为1的对数
for (i = b + 1; i <= d; i++) //求[b+1,d]与[1,b]的互质对数
res += b - dfs (0, b, i); //已经无法用语言形容了,我反正信了
printf ("%I64d\n", res);
}
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值