• HDU 4135:Co-prime(容斥+二进制拆分)


    Co-prime

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6869    Accepted Submission(s): 2710

     

    Problem 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 <= 1015) and (1 <=N <= 109).

    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,n,求区间[a.b]中有多少和n互质的数

    思路

    先把n的质因子记录下来,然后利用容斥+二进制拆分分解求出1~(a-1)和1~b之间的与n互质的个数ans1和ans2,然后减去区间中数的个数减去(ans2-ans1)即可

    AC代码

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <limits.h>
    #include <map>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <set>
    #include <string>
    #define ll long long
    #define ms(a) memset(a,0,sizeof(a))
    #define pi acos(-1.0)
    #define INF 0x3f3f3f3f
    const double E=exp(1);
    const int maxn=1e6+10;
    using namespace std;
    int A[maxn];//用来存放质因子
    ll gcd(ll a,ll b)
    {
    	return b?gcd(b,a%b):a;
    }
    ll lcm(ll a,ll b)
    {
    	return a/gcd(a,b)*b;
    }
    int main(int argc, char const *argv[])
    {
    	int t;
    	ll a,b,n;
    	scanf("%d",&t);
    	int x=0;
    	while(t--)
    	{
    		ll ans1,ans;
    		ans=ans1=0;
    		map<int,int>mmp;//记录质因子是否出现过
    		scanf("%lld%lld%lld",&a,&b,&n);
    		ll m=n;
    		int k=0;
    		for(int i=2;i*i<=m;i++)
    		{
    			if(m%i==0)
    			{
    				while(m%i==0)
    				{
    					if(mmp[i]==0)
    					{
    						A[k++]=i;
    						mmp[i]=1;
    					}
    					m/=i;
    				}
    			}
    		}
    		if(m>1)
    		{
    			A[k++]=m;
    			mmp[m]=1;
    		}
    		for(int i=1;i<(1<<k);i++)
    		{
    			int cnt=0;
    			ll tmp=1;
    			for(int j=0;j<k;j++)
    			{
    				if(i>>j&1)
    				{
    					cnt++;
    					tmp=lcm(tmp,A[j]);
    				}
    			}
    			if(cnt&1)
    			{
    				ans+=(a-1)/tmp;
    				ans1+=(b)/tmp;
    			}
    			else
    			{
    				ans-=(a-1)/tmp;
    				ans1-=b/tmp;
    			}
    		}
    		printf("Case #%d: %lld
    ",++x,(b-a+1)-ans1+ans);
    	}
    	return 0;
    }
  • 相关阅读:
    利用 PhpStorm、Idea 等 IDE 如何 运行/调试 Go 程序 ?
    [Go] 函数/方法 的 变参
    PHP 如何显示大数字,防止显示为 科学计数法 形式
    PHP协程 详解
    [Go] 路径、目录名、包名、文件名
    [Go] 复合类型(数组、切片、字典、结构体)变量的 初始化 及 注意事项
    Firefox 及其 插件“个性化设置”备份
    Go
    [Go] template 常用方法详解 及 注意事项
    Go
  • 原文地址:https://www.cnblogs.com/Friends-A/p/10324443.html
Copyright © 2020-2023  润新知