HDU4135Co-prime(容斥原理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4135

题目解析:

给你一个闭区间[A,B](1 <= A <= B <= 1015),以及一个正整数N,求[A,B]中与N互质的个数,可以先求[1,B]中与N互质的个数,在求[1,A-1]中与N互质的个数。之后两结果相减便得到答案。另外这题只要知道质因数的性质就很容易做了。任意一个正整数(除了1)都可以分解成有限个质数因子的乘积。那么假如两个数互质,那么这两个数没有相同质因子。所以若一个数跟n不互质,那么这个的数的质因子肯定也有属于n的质因子,那么就用容斥原理求出所有跟n不互质的所有数的个数。然后再用总的减去即可。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
typedef __int64 ll;
ll x,b,n,sum,sum2,top,a[10001];
ll gcd(ll A,ll B)
{
    return B==0?A:gcd(B,A%B);
}
void dfs(ll now,ll num,ll lcm,ll &sum)
{
    lcm=a[now]/gcd(a[now],lcm)*lcm;
    if(num&1)
    {
        sum+=b/lcm;
    }
    else
    {
        sum-=b/lcm;
    }
    for(int i=now+1; i<top; i++)
        dfs(i,num+1,lcm,sum);
}
void dfs2(ll now,ll num,ll lcm,ll &sum2)
{
    lcm=a[now]/gcd(a[now],lcm)*lcm;
    if(num&1)
    {
        sum2+=(x-1)/lcm;
    }
    else
    {
        sum2-=(x-1)/lcm;
    }
    for(int i=now+1; i<top; i++)
        dfs2(i,num+1,lcm,sum2);
}
int main()
{
    int T;
    ll temp;
    scanf("%d",&T);
    for(int K=1; K<=T; K++)
    {
        scanf("%I64d%I64d%I64d",&x,&b,&n);
        sum=0;
        sum2=0;
        top=0;
        temp=n;
        for(int i=2; i*i<=temp; i++)
        {
            if(temp%i==0)
            {
                temp/=i;
                a[top++]=i;
                while(temp%i==0)
                {
                    temp/=i;
                }
            }
        }
        if(temp!=1)
            a[top++]=temp;
        for(int i=0; i<top; i++)
        {
            dfs(i,1,a[i],sum);
        }
        for(int i=0; i<top; i++)
        {
            dfs2(i,1,a[i],sum2);
        }
        sum=(b-x+1)-(sum-sum2);
        printf("Case #%d: %I64d\n",K,sum);
    }
    return 0;
}
时间: 2024-11-05 14:43:42

HDU4135Co-prime(容斥原理)的相关文章

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f

[容斥原理] hdu 4135 Co-prime

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4135 Co-prime Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1176    Accepted Submission(s): 427 Problem Description Given a number N, you are a

容斥原理 求M以内有多少个跟N是互质的

开始系统的学习容斥原理!通常我们求1-n中与n互质的数的个数都是用欧拉函数! 但如果n比较大或者是求1-m中与n互质的数的个数等等问题,要想时间效率高的话还是用容斥原理! 本题是求[a,b]中与n互质的数的个数,可以转换成求[1,b]中与n互质的数个数减去[1,a-1]与n互质的数的个数. #include<iostream> #include<cstdio> #include<cstring> using namespace std; #define LL long

poj 2773(容斥原理)

容斥原理入门题吧. Happy 2006 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 9798   Accepted: 3341 Description Two positive integers are said to be relatively prime to each other if the Great Common Divisor (GCD) is 1. For instance, 1, 3, 5, 7,

HDU-4407-Sum(容斥原理)

Problem Description XXX is puzzled with the question below: 1, 2, 3, ..., n (1<=n<=400000) are placed in a line. There are m (1<=m<=1000) operations of two kinds. Operation 1: among the x-th number to the y-th number (inclusive), get the sum o

2014 Super Training #3 H Tmutarakan Exams --容斥原理

原题: URAL 1091  http://acm.timus.ru/problem.aspx?space=1&num=1091 题意:要求找出K个不同的数字使他们有一个大于1的公约数,且所有的数字都不能大于一个指定的数字S. 解法:可以考虑每个S内的素数,此素数和它的所有倍数构成一个集合,则可以在这些集合中任意去k个元素,C(n,k)即为这种情况下的方法种数,比如K = 3,S = 10, 则可以形成3个集合: {2,4,6,8,10} , {3,6,9}, {5,10} ,第一个集合C(5,

hdu 5072 计数+容斥原理

/* 题意: 给出n个数(n<100000), 每个数都不大于100000,数字不会有重复.现在随意抽出3个,问三个彼此互质 或者 三个彼此不互质的数目有多少. 思路: 这道题的原型是同色三角形, 可能现场很多队伍都知道这个模型, 所以这道题当时过的队伍还是挺多的. 这道题反着想,就是三个数中只有一对互质 或者只有两对互质的个数. 研究后发现 对于每个数字求出与其不互质的个数k 那么 sum ( k*(n-1-k) )/2 就是相反的数目, 所以最终的答案就是 C(n,3) - sum ( k*

bzoj 2005 能量采集 - 容斥原理

栋栋有一块长方形的地,他在地上种了一种能量植物,这种植物可以采集太阳光的能量.在这些植物采集能量后, 栋栋再使用一个能量汇集机器把这些植物采集到的能量汇集到一起. 栋栋的植物种得非常整齐,一共有n列,每列 有m棵,植物的横竖间距都一样,因此对于每一棵植物,栋栋可以用一个坐标(x, y)来表示,其中x的范围是1至n, 表示是在第x列,y的范围是1至m,表示是在第x列的第y棵. 由于能量汇集机器较大,不便移动,栋栋将它放在了 一个角上,坐标正好是(0, 0). 能量汇集机器在汇集的过程中有一定的能量

hdu 1695 GCD(欧拉函数+容斥原理)

http://acm.hdu.edu.cn/showproblem.php? pid=1695 非常经典的题.同一时候感觉也非常难. 在区间[a,b]和[c,d]内分别随意取出一个数x,y,使得gcd(x,y) = k.问这种(x,y)有多少对.能够觉得a,c均为1,并且gcd(5,7)与gcd(7,5)是同一种. 由于gcd(x,y) = k,那么gcd(x/k,y/k) = 1.也就是求区间[1,b/k]和[1,d/k]内这种(x,y)对使得gcd(x,y) = 1. 为了防止计数反复,首先

容斥原理算法总结(bzoj 2986 2839)

容斥原理是一个从小学就开始学习的算法.但是很多难题现在都觉得做的十分吃力. 容斥原理大概有两种表现形式,一种是按照倍数进行容斥,这个东西直接用莫比乌斯函数就可以了. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 200100 typedef long long qword; bool pfl