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

HDU 4135 Co-prime (容斥原理)

时间:2015-07-20 23:44:39      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:数论   acm   容斥原理   

题目戳这里

题意:求一个区间[a,b]中有多少个与n互素的数。

思路:

这道题是容斥原理的模板题之一,容斥原理请参考容斥原理详述,很好的一篇文章。

[a,b]中与n互素的数目可转化为[1,b]-[1,a-1]的数目。


给出整数n和r。求区间[1;r]中与n互素的数的个数的方法:

解决它的逆问题,求不与n互素的数的个数。  

考虑n的所有素因子pi(i=1…k)

在[1;r]中有多少数能被pi整除呢?它就是:

       技术分享

然而,如果我们单纯将所有结果相加,会得到错误答案。有些数可能被统计多次(被好几个素因子整除)。所以,我们要运用容斥原理来解决。

我们可以用o(2^k)的算法求出所有的pi组合,然后计算每种组合的pi乘积,通过容斥原理来对结果进行加减处理。


code:

/*
*Author : Flint_x 
*Created Time : 2015-07-20 13:22:56 
*File name : whust1_H.cpp 
*/

#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;

#define cls(a) memset(a,0,sizeof(a))
#define rise(i,a,b) for(int i = a ; i <= b ; i++)
#define fall(i,a,b) for(int i = a ; i >= b ; i--)

vector<lint> p;
lint solve (lint n, lint r) {
        p.clear();
        for (lint i=2; i*i<=n; ++i)
               if (n % i == 0) {
                       p.push_back (i);
                       while (n % i == 0)
                               n /= i;
               }
        if (n > 1)
               p.push_back (n);
        lint sum = 0;
        for (lint msk=1; msk<(1<<p.size()); ++msk) {
               lint mult = 1,bits = 0;
               for (lint i=0; i<(lint)p.size(); ++i)
                       if (msk & (1<<i)) {
                               mult *= p[i];
                               bits++;
                       }
               lint cur = r / mult;
//               cout << cur << endl;
               if (bits % 2 == 1)
                    sum += cur;
               else
                    sum -= cur;
        }
        return r - sum;
}

int main(){
//    freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
	int T;
	cin >> T;
	rise(kase,1,T){
		lint a,b,n;
		cin >> a >> b >> n;
		lint ans = solve(n,b) - solve(n,a-1);
		cout << "Case #" << kase << ": " << ans << endl;
		
		
	}
    return 0;
}
        



版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 4135 Co-prime (容斥原理)

标签:数论   acm   容斥原理   

原文地址:http://blog.csdn.net/qq_15714857/article/details/46972865

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