zoukankan      html  css  js  c++  java
  • HDU 1695 GCD 欧拉函数+容斥原理+质因数分解

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1695

    题意:在[a,b]中的x,在[c,d]中的y,求x与y的最大公约数为k的组合有多少。(a=1, a <= b <= 100000, c=1, c <= d <= 100000, 0 <= k <= 100000)

    思路:由于x与y的最大公约数为k,所以xx=x/k与yy=y/k一定互质。要从a/k和b/k之中选择互质的数,枚举1~b/k,当选择的yy小于等于a/k时,能够选择的xx数为Euler(yy),当yy大于a/k时,就要用容斥原理来找到yy的质因数,在a/k范围内找到与yy互质的数。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <map>
    #include <cstdlib>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <ctype.h>
    #include <algorithm>
    #include <string>
    #include <set>
    #include <ctime>
    #define PI acos(-1.0)
    #define maxn 1<<20
    #define INF 0x7fffffff
    #define eps 1e-8
    typedef long long LL;
    typedef unsigned long long ULL;
    using namespace std;
    LL ans=0;
    LL S=0;
    LL sum2;
    LL euler[100050];
    void init()
    {
        memset(euler,0,sizeof(euler));
        euler[1] = 1;
        for(int i = 2; i <= 100000; i++)
            if(!euler[i])
                for(int j = i; j <= 100000; j += i)
                {
                    if(!euler[j])
                        euler[j] = j;
                    euler[j] = euler[j]/i*(i-1);
                }
    }
    void factor(int n,int a[maxn],int b[maxn],LL &tt)
    {
        int temp,i,now;
        temp=(int)((double)sqrt(n)+1);
        tt=0;
        now=n;
        for(i=2; i<=temp; i++)
        {
            if(now%i==0)
            {
                a[++tt]=i;
                b[tt]=0;
                while(now%i==0)
                {
                    ++b[tt];
                    now/=i;
                }
            }
        }
        if(now!=1)
        {
            a[++tt]=now;
            b[tt]=1;
        }
    }
    int dfs(int aa[],int pos,int res,int sum,int b,int tot)//res乘积,sum乘数的个数
    {
        if(pos+1<=tot)
            dfs(aa,pos+1,res,sum,b,tot);
        sum++;
        res*=aa[pos];
        if(sum%2)
            sum2+=b/res;
        else
            sum2-=b/res;
        if(pos+1<=tot)
            dfs(aa,pos+1,res,sum,b,tot);
        return 0;
    }
    int main()
    {
        int T,tt=0,aa[40],bb[40];
        init();
        while(~scanf("%d",&T))
        {
            tt=0;
            while(T--)
            {
                tt++;
                int a,b,c,d,k;
                scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
                printf("Case %d: ",tt);
                if(k==0)
                {
                    printf("0
    ");
                    continue;
                }
                if(d<b)
                    swap(b,d);
                b/=k;
                d/=k;
                if(!b)
                {
                    printf("0
    ");
                    continue;
                }
                ans=0;
                for(int i=1; i<=b; i++)
                    ans+=euler[i];
                for(int i=b+1; i<=d; i++)
                {
                    sum2=0;
                    factor(i,aa,bb,S);
                    dfs(aa,1,1,0,b,S);
                    ans+=b-sum2;
                }
                printf("%I64d
    ",ans);
            }
        }
        return 0;
    }
    


  • 相关阅读:
    详解Webpack-dev-server的proxy用法
    .sync修饰符
    [Vue]createElement参数
    ElementUi学习笔记
    A5000项目阅读笔记
    webpack学习-10天搞定webpack4
    bhuilder 采坑日记-大小写问题
    angularjs:$$animateJs is not a function 错误
    webpack4 Cannot find module '@babel/core'
    算法-图论-最短路径-Dijsktra算法
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4062697.html
Copyright © 2011-2022 走看看