博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
容斥 - HDU 4135 Co-prime
阅读量:5782 次
发布时间:2019-06-18

本文共 1730 字,大约阅读时间需要 5 分钟。

Co-prime 

Problem's Link:


推荐:

Mean: 

给你一个区间[l,r]和一个数n,求[l,r]中有多少个数与n互素。

analyse:

经典的容斥原理题。

如果题目是说求1~n中有多少个数与n互质,我们一定反应应该是欧拉函数。

但是如果n特别大或者说是求某个给定区间与n互素的个数,这时用欧拉函数就行不通。

容斥做法:首先我们可以在O(sqrt(n))内求出n的所有质因数p1,p2,p3....pk。

对于每个质因数pi,1~r中不与它互素的个数就是r/pi。

然后就是如何容斥了?

首先我们来分析,n<=1e9,那么n的质因数的个数最多不超过9个,那么我们就可以对n的所有质因数进行组合来计算。

例如:30的质因数有3个(2,3,5),我们可以用二进制来表示所有的情况:

001: 5

010: 3

011: 3 5

100: 2

101: 2 5

110: 2 3

111: 2 3 5

假设有k个质因数,那么只需用2^k-1个数的二进制来表示即可。

剩下的就是容斥了,设cnt为1的个数(选中的质因数的个数),当cnt为奇数,sum加上此次的;cnt为偶数,sum减去此次的。

具体看代码。

Time complexity: O(N)

 

Source code: 

/*
* this code is made by crazyacking
* Verdict: Accepted
* Submission Date: 2015-08-10-19.49
* Time: 0MS
* Memory: 137KB
*/
#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#define  LL long long
#define  ULL unsigned long long
using
namespace
std;
LL
solve(
LL
r
,
LL n)
{
     
vector
<
LL
>
ve;
     
LL
up
=(
LL)
sqrt(n);
     
for(
LL
i
=
2;
i
<=
up;
++
i)
     
{
           
if(n
%
i
==
0)
           
{
                 
ve
.
push_back(
i);
                 
while(n
%
i
==
0)
                       n
/=
i;
           
}
     
}
     
if(n
>
1)
ve
.
push_back(n);
     
LL
sum
=
0
,
si
=
ve
.
size();
     
up
=(
1
<<
si)
-
1;
     
for(
LL
i
=
1;
i
<=
up;
++
i)
     
{
           
LL
tmp
=
i
,
bits
=
0
,
mul
=
1
,
cnt
=
0;
           
while(
tmp)
           
{
                 
if(
tmp
&
1)
                 
{
                       
mul
*=
ve
[
bits
];
                       
++
cnt;
                 
}
                 
++
bits;
                 
tmp
=
tmp
>>
1;
           
}
           
LL
cur
=
r
/
mul;
           
if(
cnt
&
1)
sum
+=
cur;
           
else
sum
-=
cur;
     
}
     
return
sum;
}
int
main()
{
     
ios_base
::
sync_with_stdio(
false);
     
cin
.
tie(
0);
     
LL
t
,
cas
=
1;
     
cin
>>
t;
     
while(
t
--)
     
{
           
LL
l
,
r
,n;
           
cin
>>
l
>>
r
>>n;
           
if(
l
>
r)
swap(
l
,
r);
           
printf(
"Case #%lld: %lld
\n
"
,
cas
++
,
r
-
l
+
1
-(
solve(
r
,n)
-
solve(
l
-
1
,n)));
     
}
     
return
0;
}
/*
*/

 

转载地址:http://mpcyx.baihongyu.com/

你可能感兴趣的文章
ASP.NET MVC是否会成为ASP.NET未来主流的UI平台?
查看>>
[转] 企业版IDP的申请及“In House”发布
查看>>
hadoop实战之动态添加节点
查看>>
跟小静读CLR via C#(15)--String,熟悉而又陌生
查看>>
《转》OpenStack Ceilometer 安装配置和API说明
查看>>
用Nifi 从web api 取数据到HDFS
查看>>
Swift - 用UIScrollView实现视差动画效果
查看>>
iOS开发之——从零开始完成页面切换形变动画
查看>>
微信扫描二维码登录网站技术原理
查看>>
Mac休眠之后唤醒时无法使用鼠标
查看>>
删除变量PHP之session的使用
查看>>
张小龙:用停留时长衡量一个APP的好坏是错误的!
查看>>
聚焦ISC 2018:几位大佬都说了点啥?
查看>>
UFS 2.1和UFS 2.0差距到底多大?跑分还有很多学问
查看>>
特斯拉最大外部投资者买入蔚来汽车 持股增至11.4%
查看>>
我爱我家副总裁胡景晖离职:左晖给谢勇一个电话就切割了我
查看>>
“年画重回春节”系列活动亮相北京
查看>>
《明星大侦探》迎来收官 系列互动微剧将上线
查看>>
重庆新增一批市级历史文化名镇、街区和传统风貌区
查看>>
区块链每日投资指南——风险篇(0109)
查看>>