GCD (区间数的质因子打表+容斥原理)

GCD

HDU - 1695

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.

InputThe 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. 
OutputFor 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

题意:求[a,b]区间和[c,d]区间里面gcd(x, y) = k的数的对数(1<=x<=b , 1<= y <= d)。(本题中a,b均为1)

题解:

  令区间端点均除以k,那么就变成了求[a/k,b/k]区间里面和[c/k,d/k]区间里面gcd(x,y)==1的对数,即求两个区间里面互质的数的对数,因为1 2和2 1算是一对,所以我们需要把相对小的区间遍历一遍,大的区间从小区间+1开始遍历,即可避免这个问题。

  注意先对每个数的质因子打个表,不然会超时。

  注意排除k==0的情况。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<vector>
  5 #include<algorithm>
  6 using namespace std;
  7 typedef long long ll;
  8 const ll maxn=1e5+10;
  9 ll n,cnt;
 10 ll ans;
 11 vector<ll>prime[maxn];
 12 ll l1,l2,r1,r2,k;
 13 ll l,r;
 14 bool vis[maxn];
 15 ll gcd(ll a,ll b)
 16 {
 17     if(b==0)
 18         return a;
 19     else
 20         return gcd(b,a%b);
 21 }
 22 ll Lcm(ll a,ll b)
 23 {
 24     return a*b/gcd(a,b);
 25 }
 26 ll get_prime(ll x)
 27 {
 28     ll t=x;
 29     for(ll i=2;i*i<=x;i++)
 30     {
 31         if(x%i)
 32             continue;
 33         while(x%i==0)
 34             x/=i;
 35         prime[t].push_back(i);
 36     }
 37     if(x!=1)
 38         prime[t].push_back(x);
 39 }
 40 ll casen;
 41 void dfs(ll m,ll x,ll th,ll now,ll step)
 42 {
 43
 44     ll lcm=Lcm(prime[x][th],now);
 45     if(step&1)
 46     {
 47         ans+=m/lcm;
 48     }
 49     else
 50     {
 51         ans-=m/lcm;
 52     }
 53     for(ll i=th+1;i<prime[x].size();i++)
 54         dfs(m,x,i,lcm,step+1);
 55 }
 56 int main()
 57 {
 58     ll casen;
 59     scanf("%lld",&casen);
 60     ll ca=1;
 61     for(ll i=2;i<maxn;i++)//注意先打表
 62     {
 63         get_prime(i);
 64     }
 65     while(casen--)
 66     {
 67         ans=0;
 68         cnt=0;
 69         scanf("%lld%lld%lld%lld%lld",&l1,&r1,&l2,&r2,&k);
 70         if(k==0)//注意判零
 71         {
 72             printf("Case %lld: 0\n",ca++);
 73             continue;
 74         }
 75         r1/=k;
 76         r2/=k;
 77         if(r1>r2)
 78             swap(r1,r2);//注意判断两个区间谁大谁小
 79         ll sum=0;
 80         for(ll i=l1;i<=r1;i++)
 81         {
 82
 83             ans=0;
 84             for(ll j=0;j<prime[i].size();j++)
 85             {
 86                 dfs(i-1,i,j,prime[i][j],1);
 87             }
 88             ll le=i-1-ans;
 89             ans=0;
 90             for(ll j=0;j<prime[i].size();j++)
 91             {
 92                 dfs(r2,i,j,prime[i][j],1);
 93             }
 94             ll ri=r2-ans;
 95             sum+=ri-le;
 96         }
 97
 98         printf("Case %lld: %lld\n",ca++,sum);
 99     }
100 }

原文地址:https://www.cnblogs.com/1013star/p/9896262.html

时间: 2024-11-05 15:49:31

GCD (区间数的质因子打表+容斥原理)的相关文章

HDU 4497 GCD and LCM(分解质因子+排列组合)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4497 题意:已知GCD(x, y, z) = G,LCM(x, y, z) = L.告诉你G.L,求满足要求的(x, y, z)有多少组,并且要考虑顺序. 思路:如果L%G != 0显然不存在这样的(x, y, z),相反肯定存在.具体做法就是将L/G分解质因子,得到:L/G = P1^t1 * P2^t2 * ... * Pk^tk,我们来考虑任意一个因子Pi^ti,此时(x/G, y/G, z/

poj3696 快速幂的优化+欧拉函数+gcd的优化+互质

这题满满的黑科技orz 题意:给出L,要求求出最小的全部由8组成的数(eg: 8,88,888,8888,88888,.......),且这个数是L的倍数 sol:全部由8组成的数可以这样表示:((10^x)-1)*(8/9) 那么有m=((10^x)-1)*(8/9)=k*L,answer即满足条件的最小的x 性质1:若ax=by且a和b互质,那么说明a中没有任何b的质因子,b的质因子一定都在x里.所以x是b的倍数. 所以先想方设法在等式中构造两个互质的数以便化简.我们取p=8/gcd(8,L

(hdu step 2.1.3)Largest prime factor(求一个数的最大质因子的位置)

题目: Largest prime factor Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4868 Accepted Submission(s): 1452   Problem Description Everybody knows any number can be combined by the prime number.Now,

HDU 4135 Co-prime (容斥+分解质因子)

<题目链接> 题目大意: 给定区间[A,B](1 <= A <= B <= 10 15)和N(1 <=N <= 10 9),求出该区间中与N互质的数的个数. 解题分析: 将求区间[A,B]与N互质的数转化成求[1,B] 区间与N互质的个数  -  [1,A-1]中与N互质的个数.同时,因为直接求区间内与N互质的数不好求,我们从反面入手,求出与N不互质的数,借鉴埃筛的思想,我们先求出N的所有质因子,然后将这些质因子在区间内倍数的个数全部求出(即与N不互质的数),再用

UVA10892 - LCM Cardinality(分解质因子)

题目链接 题意:输入正整数n,统计有多少对正整数a <= b,满足lcm(a, b) = n. 思路:分解质因子,然后直接暴力求出对数 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; const int MA

洛谷P1890 gcd区间 [2017年6月计划 数论09]

P1890 gcd区间 题目描述 给定一行n个正整数a[1]..a[n]. m次询问,每次询问给定一个区间[L,R],输出a[L]..a[R]的最大公因数. 输入输出格式 输入格式: 第一行两个整数n,m. 第二行n个整数表示a[1]..a[n]. 以下m行,每行2个整数表示询问区间的左右端点. 保证输入数据合法. 输出格式: 共m行,每行表示一个询问的答案. 输入输出样例 输入样例#1: 5 3 4 12 3 6 7 1 3 2 3 5 5 输出样例#1: 1 3 7 说明 对于30%的数据,

BNU 13259.Story of Tomisu Ghost 分解质因子

Story of Tomisu Ghost It is now 2150 AD and problem-setters are having a horrified time as the ghost of a problem-setter from the past, Mr. Tomisu, is frequently disturbing them. As always is the case in most common ghost stories, Mr. Tomisu has an u

hdu 5428 质因子

问题描述有一个数列,FancyCoder沉迷于研究这个数列的乘积相关问题,但是它们的乘积往往非常大.幸运的是,FancyCoder只需要找到这个巨大乘积的最小的满足如下规则的因子:这个因子包含大于两个因子(包括它本身:比如,4有3个因子,因此它是满足这个要求的一个数).你需要找到这个数字并输出它.但是我们知道,对于某些数可能没有这样的因子:在这样的情况下,请输出-1. 这个因子包含大于两个因子也就是说必须包含三个因子可以为本身求出所有数的所有质因子中最小的两个,相乘就是答案.如果所有数字的质因子

POJ2992:Divisors(求N!因子的个数,乘性函数,分解n!的质因子)

题目链接:http://poj.org/problem?id=2992 题目要求:Your task in this problem is to determine the number of divisors of Cnk. Just for fun -- or do you need any special reason for such a useful computation? 题目解析:这题也是TLE了无数遍,首先说一下求因子数目的函数是积性函数,积性函数即f(n)=f(a)*f(b)