zoukankan      html  css  js  c++  java
  • hdu 2841 Visible Trees(容斥原理)

    http://acm.hdu.edu.cn/showproblem.php?pid=2841


    有一个n*m的方格,从(1,1)開始,每一个点有一棵树,一个人站在(0,0)点,问他能看到几棵树。当(0,0)和另外的点在一条直线上时他仅仅能看到近期的一棵。


    题目意在求在m*n的方格中有多少种y/x,由于两个y/x相等的点仅仅能看到一个。有多少种y/x也就是有多少 个(x,y)x与y互质。当中(1<=x<=m,1<=n<=y)。

    这样就上一题类似了,求一个区间[1,m]内与i的互质的数的个数。这里1<=i<=n。先求出与i不互质的,对i分解质因子然后容斥。


    #include <stdio.h>
    #include <iostream>
    #include <map>
    #include <set>
    #include <bitset>
    #include <list>
    #include <stack>
    #include <vector>
    #include <math.h>
    #include <string.h>
    #include <queue>
    #include <string>
    #include <stdlib.h>
    #include <algorithm>
    #define LL __int64
    //#define LL long long
    #define eps 1e-9
    #define PI acos(-1.0)
    using namespace std;
    const LL INF = 1<<30;
    const int maxn = 100010;
    
    LL ans;
    int n,m;
    int fac[maxn];
    int prime[maxn];
    int facCnt;
    
    void getPrime()
    {
        bool flag[maxn];
        memset(flag,false,sizeof(flag));
        prime[0] = 0;
    
        for(int i = 2; i < maxn; i++)
        {
            if(flag[i] == false)
                prime[++prime[0]] = i;
            for(int j = 1; j <= prime[0]&&i*prime[j]<maxn; j++)
            {
                flag[i*prime[j]] = true;
                if(i % prime[j] == 0)
                    break;
            }
        }
    }
    
    void getFac(int num)
    {
        int tmp = num;
        facCnt = 0;
        for(int i = 1; i <= prime[0] && prime[i]*prime[i] <= tmp; i++)
        {
            if(tmp % prime[i] == 0)
            {
                fac[facCnt++] = prime[i];
                while(tmp%prime[i] == 0)
                    tmp /= prime[i];
            }
            if(tmp == 1)
                break;
        }
        if(tmp > 1)
            fac[facCnt++] = tmp;
    }
    
    LL solve(int m)
    {
        //队列数组
        int que[110];
        int l = 0;
        que[l++] = 1;
    
        for(int i = 0; i < facCnt; i++)
        {
            int k = l;
            for(int j = 0; j < k; j++)
                que[l++] = fac[i]*que[j]*(-1);
        }
    
        LL anw = 0;
        for(int i = 0; i < l; i++)
            anw += m/que[i];
        return anw;
    }
    
    int main()
    {
        int test;
        scanf("%d",&test);
        getPrime();
        for(int item = 1; item <= test; item++)
        {
            scanf("%d %d",&n,&m);
            if(n > m)
                swap(n,m);
            ans = 0;
            for(int i = 1; i <= n; i++)
            {
                getFac(i);
                ans += solve(m);
            }
            printf("%I64d
    ",ans);
        }
        return 0;
    }
    




  • 相关阅读:
    Xshell4连接,Linux系统中文显示乱码解决办法
    Linux系统英文切换中文
    解决VM安装VMTools后错误提示,实现文件共享
    v
    如何安装VM Tool软件包
    Jbpm工作流表补数记录
    【转】Informix数据表结构分析资料整理之约束查询代码
    storm源码之storm代码结构【译】
    Python学习笔记第一天
    python 连接 redis cluster 集群二种方法
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6814001.html
Copyright © 2011-2022 走看看