zoukankan      html  css  js  c++  java
  • hdu 1659 综合数论+ 筛选欧拉函数 +质因子 +容斥原理

    题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=1695

    GCD

    Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 4947    Accepted Submission(s): 1772


    Problem Description
    Given 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k. GCD(x, y) means the greatest common divisor of x and y. Since the number of choices may be very large, you're only required to output the total number of different number pairs.
    Please notice that, (x=5, y=7) and (x=7, y=5) are considered to be the same.

    Yoiu can assume that a = c = 1 in all test cases.
     
    Input
    The input consists of several test cases. The first line of the input is the number of the cases. There are no more than 3,000 cases.
    Each case contains five integers: a, b, c, d, k, 0 < a <= b <= 100,000, 0 < c <= d <= 100,000, 0 <= k <= 100,000, as described above.
     
    Output
    For each test case, print the number of choices. Use the format in the example.
     
    Sample Input
    2 1 3 1 5 1 1 11014 1 14409 9
     
    Sample Output
    Case 1: 9 Case 2: 736427
    Hint
    For the first sample input, all the 9 pairs of numbers are (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (3, 5).
     
    分析:
    1:求(1,2,..., a)中的x 与(1,2,...,b)中的y 中的对数 使得: gcd(x,y) = k
    可以转换成 求 (1,,2 ,..., a/k) 与(1,2,..., b/k) 中的对数 使得gcd(x,y) =1
    2: (3,1) = (1,3) 算一种, 故我们只需要满足x>y 这样的组合数
    3:令a/k =Max >  b/k = Min, 
    考虑(1,2,...,Max)中的数n,
    如果n<= Min  , 则  求n的欧拉函数,即小于n 且与n 互质的个数, 然后累加n 的欧拉函数值 , 当n= (1,2 , ...,Min)
    如果n>Min , 求n 与(1,2,..., Min) 互质的个数, 可以转换成, 集合{1,2,..., Min}中有多少个数,满足不能被n的质因子集合M{p1,p2,...pm}中的任意数整除,容斥原理+质因子。
    代码如下:
    #include<iostream>
    #include<stdlib.h>
    #include<stdio.h>
    #include<math.h>
    #include<string.h>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<map>
    #define N 100005
    using namespace std;
    
    typedef long long LL;
    LL euler[N];
    int Min, Max;
    int p[N][10];//  二维存的是 N 的质因子
    int num[N];  // 记录的是 P二维质因子的个数
    // 筛选得到 欧拉函数和 质因子
    void init()
    {
        int i,j;
        memset(num, 0 , sizeof(num));
        memset(euler , 0 ,sizeof(euler));
        euler[1]=1;
        for( i =2 ; i<N ; i++) // 质数从2开始
        {
            if(!euler[i])  //i是质数
            {
                for(j=i; j<N ;j+=i)
                {
                    if(!euler[j])  //初次访问j
                        euler[j]=j;
                    euler[j]=euler[j]*(i-1)/i; // 欧拉函数
                    p[j][num[j]++] = i; // 记录j质因子:第num[j] 位置的是质因子i
                   // printf("p[%d][%d]=%d
    ",j,num[j]-1,i);
                }
            }
            euler[i]+=euler[i-1];  // ,题目要求,前i个数的欧拉函数值累加和
        }
    }
    // 容斥原理 值为q,当前点(质因子的下标号),数深(树根为1),
    void dfs(int q ,int now , int count , LL lcm ,LL &sum)  // 计算Min与q不互质的个数
    {
        if(count>1)
            lcm=p[q][now]*lcm;
        if(count &1)
            sum+=Min/lcm; 
        else
            sum-=Min/lcm;
        for(int i=now+1 ;i <num[q] ; i++)
            dfs(q,i,count+1,lcm, sum);
    }
    int main()
    {
        int  a,b , k,ans=1,t;
        LL temp;
        cin>>t;
        init();
        while(t--)
        {
            scanf("%d%d%d%d%d",&a,&a,&b,&b,&k);
            if(k==0)
            {
                printf("Case %d: 0
    ",ans++);
                continue;
            }
    
            LL sum_=0;
            Max=a>b?a:b;
            Min=a<b?a:b;
            Max/=k;
            Min/=k;
            sum_=euler[Min];
            for(int i=Min+1 ; i<=Max ; i++)  // 枚举 i
            {
                temp=0;
                for(int j=0; j<num[i] ; j++) // 求Min与i不互质的个数。
                    dfs(i,j,1,p[i][j],temp);
                sum_+=Min-temp;  // 求Min 与i 互质的个数
            }
    
            printf("Case %d: %I64d
    ",ans++,sum_);
    
        }
        return 0;
    }
     
  • 相关阅读:
    『TensorFlow』模型保存和载入方法汇总
    『cs231n』作业2选讲_通过代码理解Dropout
    『cs231n』作业2选讲_通过代码理解优化器
    『科学计算』图像检测微型demo
    『cs231n』作业1选讲_通过代码理解KNN&交叉验证&SVM
    大数据技术之_16_Scala学习_13_Scala语言的数据结构和算法_Scala学习之旅收官之作
    IDEA 取消参数名称(形参名)提示
    大数据技术之_16_Scala学习_12_设计模式+泛型、上下界、视图界定、上下文界定、协变逆变不变
    大数据技术之_16_Scala学习_11_客户信息管理系统+并发编程模型 Akka+Akka 网络编程-小黄鸡客服案例+Akka 网络编程-Spark Master Worker 进程通讯项目
    大数据技术之_16_Scala学习_10_使用递归的方式去思考,去编程+作业07/08/09
  • 原文地址:https://www.cnblogs.com/zn505119020/p/3597075.html
Copyright © 2011-2022 走看看