HDU 2841 Visible Trees (数论,容斥原理)

这篇博客探讨了如何解决HDU 2841问题,即在N*M格点上计算从0,0点可见的树木数量。关键在于理解当A1/B1等于A2/B2时会有一棵树不可见,因此问题转化为找出不同比例Ai/Bi的数量。博主指出,若A和B有公共因子,可以找到等效的互质数对。利用容斥原理和预处理素因子的方法来枚举并计算互质数对,从而解决该问题。" 119959792,11228649,深入理解Java基础与特性,"['Java基础', '面向对象', 'JVM原理', 'Java集合', '多线程']
摘要由CSDN通过智能技术生成

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

题目:N*M的格点上有树,从0,0点可以看到多少棵树。

发现如果A1/B1=A2/B2那么就有一棵树看不到,所以就是找出Ai/Bi有多少种。

再可以发现A/B中,如果A,B有大于1的公约数,则A=A'*D B=B'*D,那么A/B=A'/B',也就是存在另外一组数和这种相等,则问题转换成有多少对互质的数,枚举i,从1-M中找与i互质的数,其中1<=i<=N。

容斥原理,先预处理i的所有素因子,然后容斥求就可以了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<string>
#include<algorithm>
#include<queue>
#define LL long long
#define eps 1e-7
using namespace std;
int prime[100005][20];
int cnt[100005]={0};
//筛选法求出所有素因子
void Init(){
    for(int i=2;i<=100000;i++){
        if(cnt[i]) continue;
        prime[i][0]=i;
        cnt[i]=1;
        for(int j=2;j*i<=100000;j++)
            prime[i*j][cnt[i*j]++]=i;
    }
}
LL dfs(int m,int n,int idx){
    LL ret=0;
    for(int i=idx;i<cnt[m];i++)
        ret+=n/prime[m][i]-dfs(m,n/prime[m][i],i+1);
    return ret;
}
int main(){
    Init();
    int t,n,m;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        //当i为1的时候肯定为n
        LL ans=n;
        for(int i=2;i<=m;i++)
            ans+=n-dfs(i,n,0);
        printf("%I64d\n",ans);
    }
    return 0;
}



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值