码迷,mamicode.com
首页 > 其他好文 > 详细

HLG 1807 噢啦 (欧拉函数)

时间:2014-06-20 12:07:38      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:欧拉函数   数论   

链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1807

Description
上个星期,小胖子学会了欧拉函数,他得意的说:”在a和b之间有多少个与c互素的数字,这样的简单题用欧拉就哦啦!“
可是这次三三又问小胖子,在a和b之间有多少个与c互素的数。

Input
第一行包括一个整数t,代表测试次数(1<=1000)。

接下来每一组测试次数输入a,b,c,满足(1<=a<=b<=10^15,1<=c<=10^9)。

Output
对于每组测试输出结果,占一行。
Sample Input
2

1 10 2

3 15 5

Sample Output
5

10


代码及解析如下:(数据范围好大)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cstdlib>
using namespace std;

typedef long long LL;
LL a, b, n;
vector <long long> vt;

LL solve(LL x, LL n)
{
    vt.clear();
    for(LL i=2; i*i<=n; i++) {   //对n进行素数分解
        if(n%i == 0) {
            vt.push_back(i);
            while(n%i == 0) n /= i;
        }
    }
    if(n > 1) vt.push_back(n);
    LL sum = 0, val, cnt;
    for(LL i=1; i<(1<<vt.size()); i++) {  //用二进制来1,0来表示第几个素因子是否被用到,如m=3,三个因子是2,3,5,则i=3时二进制是011,表示第2、3个因子被用到
        val = 1, cnt = 0;
        for(LL j=0; j<vt.size(); j++) {
            if(i & (1<<j)) {       //判断第几个因子目前被用到
                val *= vt[j];
                cnt++;
            }
        }
        if(cnt & 1) sum += x/val;      //容斥原理,奇加偶减
        else sum -= x/val;
    }
    return x-sum;
}

int main()
{
    int cas;
    scanf("%d", &cas);
    while(cas--) {
        cin >> a >> b >> n;
        cout << solve(b, n) - solve(a-1, n) << endl;
    }
    return 0;
}



HLG 1807 噢啦 (欧拉函数),布布扣,bubuko.com

HLG 1807 噢啦 (欧拉函数)

标签:欧拉函数   数论   

原文地址:http://blog.csdn.net/keshacookie/article/details/28408415

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!