• HDU2841 Visible Trees (容斥原理)


    主题链接http://acm.hdu.edu.cn/showproblem.php?pid=2841

    题意: 

    一个人在(0,0)点,然后前面有一个m*n的格子 ,每一个格子的节点上有一棵树。问这个人站在原地能看到多少棵树

    假设两棵树在一条直线上那么仅仅能看到最前面的一棵树。

    分析

    假设一个数的坐标为(a,b)。那么坐标为(a*k,b*k)的都不能看见。假设a,b有公因子c那么我们肯定仅仅能看到(a/c,b/c)。

    因此我们得出结论,能看到的树的横纵坐标一定互质。

    那么我们就能够把问题转化为,从[1,n]有多少个数与m里的数互质。

    那么仅仅用把[1,n]里的数都素因子分解了,然后容斥一下就搞定了。

    代码例如以下

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    using namespace std;
    
    const int maxn = 100010;
    typedef long long LL;
    
    int Prim[maxn],num[maxn][20];
    void init()
    {
        int i,j;
        memset(Prim,0,sizeof(Prim));
        for(i=1; i<=100000; i++) num[i][0]=0;
        for(i=2; i<=100000; i++)
        if(Prim[i]==0)
        {
            num[i][1]=i;
            num[i][0]++;
            for(j=i*2; j<=100000; j+=i)
            {
                num[j][++num[j][0]]=i;
                Prim[j]=1;
            }
        }
    }
    
    LL dfs(int id,int b,int now)//求不大于b的数中,与now不互质的数的个数;
    {
        LL ans=0;
        for(int i=id;i<=num[now][0];i++)
            ans+=b/num[now][i]-dfs(i+1,b/num[now][i],now);
        return ans;
    }
    
    int main()
    {
        int m,n,t;
        cin>>t;
        while(t--){
            cin>>m>>n;
            init();
            long long sum=0;
            for(int i=2;i<=m;i++)
                sum+=n-dfs(1,n,i);
            printf("%I64d
    ",sum+n);
        }
        return 0;
    }
    



    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    模拟Session原理
    练手项目通讯录
    Win 8前台开发小体会
    WP自定义控件
    任务锁和自定义控件制作
    window文件复制到linux系统下
    Linux:Ubuntu配置jdk环境变量
    ubuntu 20 安装完成,配置ip信息
    Unity骨骼优化(转)
    利用栈实现简单计算器
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4868752.html
Copyright © 2020-2023  润新知