• hdu 2841 Visible Trees


    题目链接

    一、题意

    给一个\(n*m\)的矩阵,左下角为\((1,1)\),右上角为\((n,m)\),问从\((0,0)\)点可以看到多少个点。

    二、分析

    如果\((0,0)−>(x,y)\)\((0,0)−>(x′,y′)\)两个向量共线,即\((0,0),(x,y),(x′,y′)\)三点共线,那后面的那个点\((x′,y′)\)就看不到了。

    如果三点共线,那么向量\((x′,y′)\)一定可以表示成\((kx,ky)\)(其中\(k \in Z^+\)\(k>1\),\(kx<=n,ky<=m\)),因此对于一个数对\((x,y)\),如果它们存在公因数,那么一定可以化简成最简,即互质的形式,那么这个互质的数对构成的向量应该是和原向量共线的,因此我们只能看到最前面那个互质的数对构成的点,其它不互质的都会被它前面的某个互质的挡住

    因此题目转变成求区间\([1,m],[1,n]\)之间互质数的对数

    求解办法
    选取一个区间(为了优化选取小区间)比如说选取\([1,n]\),枚举\(n\)里面的数\(i\),然后对于每个数\(i\)我们看它在\([1,m]\)区间内能找到多少互质的数,把这些结果全部累加起来即可。

    所以问题的最后变为了,给定一个数字\(x\),找出它和\(1\)\(y\)里面有多少个数互质。

    三、容斥原理解法

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 1e6 + 10;
    
    //返回1-m中与n互素的数的个数
    vector<LL> p;
    LL cal(LL n, LL m) {
        p.clear();
        for (int 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); //求n的素因子
    
        int num = p.size(); //素因子的个数
        LL s = 0;           // 1到m中与n不互素的数的个数
    
        //枚举子集,不能有空集,所以从1开始
        for (LL i = 1; i < 1 << num; i++) { //从1枚举到(2^素因子个数)
            LL cnt = 0;
            LL t = 1;
            for (LL j = 0; j < num; j++) { //枚举每个素因子
                if (i & (1 << j)) {        //有第i个因子
                    cnt++;                 //计数
                    t *= p[j];             //乘上这个质因子
                }
            }
            //容斥原理
            if (cnt & 1) //选取个数为奇数,加
                s += m / t;
            else //选取个数为偶数,减
                s -= m / t;
        }
        return m - s; //返回1-m中与n互素的数的个数
    }
    
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            LL a, b;
            scanf("%lld%lld", &a, &b);
            LL res = 0;
            //从1~n(b现在就是n)之间,找到所有与m(m现在就是i)互质的数字个数
            for (int i = 1; i <= a; i++) res += cal(i, b);
            printf("%lld\n", res);
        }
        return 0;
    }
    
  • 相关阅读:
    喜马拉雅第三方客户端开发(接口和接口数据解析)。
    jquery-easyui中datagrid扩展,隐藏显示表头功能
    backbone ,jQuery-easyui,knockoutjs的整合使用
    WPF中的瀑布流布局(TilePanel)控件
    使用this.$refs['formName'].resetFields()无法重置表单
    js获取json对象的key值
    Hash表算法详解
    Redis入门
    ASP.Net 下载大文件的实现
    后端生成二维码
  • 原文地址:https://www.cnblogs.com/littlehb/p/16392216.html
Copyright © 2020-2023  润新知