• 【数论】HDU4135:Co-prime


    Description

    Given a number N, you are asked to count the number of integers between A and B inclusive which are relatively prime to N. 
    Two integers are said to be co-prime or relatively prime if they have no common positive divisors other than 1 or, equivalently, if their greatest common divisor is 1. The number 1 is relatively prime to every integer.
     

    Input

    The first line on input contains T (0 < T <= 100) the number of test cases, each of the next T lines contains three integers A, B, N where (1 <= A <= B <= 10 15) and (1 <=N <= 10 9).
     

    Output

    For each test case, print the number of integers between A and B inclusive which are relatively prime to N. Follow the output format below.
     

    Sample Input

    2
    1 10 2
    3 15 5
     

    Sample Output

    Case #1: 5
    Case #2: 10

    Hint

    In the first test case, the five integers in range [1,10] which are relatively prime to 2 are {1,3,5,7,9}. 
             
     

    题目大意:

    给一个区间[a,b],从区间[a,b]中找出共有多少个数是与n互质的。

    思路:

    欧拉函数得到的是小于n与n互质的个数,这里是个区间。由于区间较大,不可能对[a,b]进行遍历,

    考虑计算区间[1,a-1]中与n互质的个数num1,[1,b]中与n互质的个数num2,最终结果就是两者

    相减的结果。

    现在考虑如何计算区间[1,m]中n互质的个数num,num等于 (m - 与n不互质的个数)。

    与n不互质的数就是[1,m]中n的素因子的倍数。

    例如m = 12,n = 30的情况。

    30的素因子数为2、3、5。

    [1,12]中含有2的倍数的有:(2、4、6、8、10、12) = n/2 = 6个

    [1,12]中含有3的倍数的有:(3、6、9、12) = n/3 = 4个

    [1,12]中含有5的倍数的有:(5、10) = n/5 = 2个

    与n不互质的数个数就是上边三个集合取并集的部分。这里用到了容斥定理,我用的增长的队列数组

    来实现容斥定理,具体参考代码。

     1 #include <iostream>
     2 #include <cstdio>
     3 #define ll __int64
     4 using namespace std;
     5 const int maxn = 1e5+50;
     6 ll factor[105],s[maxn],num;
     7 void getphi(ll x){
     8     num = 0;
     9     for(ll i = 2; i*i <= x; i++)
    10     {
    11         if(x % i == 0)
    12         {
    13             while(x % i == 0)
    14             {
    15                 x /= i;
    16             }
    17             factor[num++]=i;
    18         }
    19     }
    20     if(x != 1)
    21         factor[num++]=x;
    22 
    23 }
    24 ll solve(ll n)
    25 {
    26     ll k,cnt,ans;
    27     cnt=ans=0;
    28     s[cnt++]=-1;
    29     for(ll i=0;i<num;i++)
    30     {
    31         k=cnt;
    32         for(ll j=0;j<k;j++)
    33         {
    34             s[cnt++]=-1*s[j]*factor[i];
    35         }
    36     }
    37     for(ll i=1;i<cnt;i++)
    38     {
    39         ans+=n/s[i];
    40     }
    41     return ans;
    42 }
    43 int main()
    44 {
    45     int T;
    46     scanf("%d",&T);
    47     for(int i=1;i<=T;i++)
    48     {
    49         ll x,y,n;
    50         scanf("%I64d%I64d%I64d",&x,&y,&n);
    51         getphi(n);
    52         ll a=y-solve(y);
    53         ll b=x-1-solve(x-1);
    54         ll ans=a-b;
    55         printf("Case #%d: %I64d
    ",i,ans);
    56     }
    57 
    58     return 0;
    59 }
    View Code
     
  • 相关阅读:
    C# MVC解决跨站请求伪造(appscan)
    .net中关于Url传参问题
    二月项目完成小结
    sql 获取时间
    ajax提交form表单
    C# 视图遍历List数组
    C#遍历指定文件夹中的所有文件
    C#关于文件的操作
    .net 文件上传到服务器【转】
    Server.MapPath获取各级目录【转】
  • 原文地址:https://www.cnblogs.com/SoulSecret/p/8432278.html
Copyright © 2020-2023  润新知