HDU2841 Visible Trees(容斥原理)

Posted xu-daxia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU2841 Visible Trees(容斥原理)相关的知识,希望对你有一定的参考价值。

题意

这道题题意就是给出第一象限的n*m个点,求出站在原点可以看见多少个点

(1<=n,m<=1^5)

题解

这个题很仪仗队差不多,不过仪仗队是正方形。

这个是长方形。。。

这题其实就是求互质的数对的对数。

我们,一个一个的枚举i,然后就是求跟i互质的数的个数。

然后这个求跟i互质的数的个数可以用容斥原理求。(我居然才知道)

其实就是求不能整除i的所有质因子的数有多少。

我们枚举i的质因子,在值域中有多少倍数,在考虑选2,3,个质因子容斥就行了。

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 const long long N=100010;
 8 long long a[N],n,m,t,ans;
 9 long long calc(long long x){
10     long long tmp=0;
11     long long tot=0;
12     for(long long i=2;i*i<=x;i++){
13         if(x%i==0)a[++tot]=i;
14         while(x%i==0)x/=i;
15     }
16     if(x>1)a[++tot]=x;
17     for(long long i=1;i<=(1<<tot)-1;i++){
18         long long cnt=0;
19         long long num=1;
20         for(long long j=1;j<=tot;j++){
21             if((1<<j-1)&i)num*=a[j],cnt++; 
22         }
23         num=m/num;
24         if(cnt&1)tmp+=num;
25         else tmp-=num;
26     }
27     return m-tmp;
28 }
29 int main(){
30     scanf("%lld",&t);
31     while(t--){
32         scanf("%lld%lld",&n,&m);
33         ans=m;
34         for(long long i=2;i<=n;i++){
35             ans+=calc(i);
36         }
37         printf("%lld
",ans);
38     }
39     return 0;
40 }

 

以上是关于HDU2841 Visible Trees(容斥原理)的主要内容,如果未能解决你的问题,请参考以下文章

Visible Trees HDU - 2841(容斥)

Visible Trees HDU - 2841(容斥)

C - Visible Trees HDU - 2841 -莫比乌斯函数-容斥

HDU2841 Visible Trees(容斥原理)

HDU 2841 Visible Trees 数论+容斥原理

HDU 2841 Visible Trees(容斥)题解