HDU 4497 素数筛,合数分解

题意:给你两个数,G和L ,它们是一组数的GCD(最大公约数)和LCM(最小公倍数),求出满足条件的组合数,每个组合有三个数,排序不同,也算不同组合。

L : p1^t1 * p2^t2 ... * pi^ti

G: q1^s1 * q2^s2... * qi^si

(pi和qii都是素数ii)

G(最大公约数)里出现的所有数都要在L(最小公倍数)里出现,或者说L mod G=0,有人要问为什么了?其实仔细想想就清楚了,如果a,b,c的最小公倍数肯定可以被a,b,c任意一个整除,而他们的最大公约数肯定可以整除a,b,c任意一个,所里理所当然,L%G=0,如果L%G!=0说明没有符合条件的数,直接输出0就好了。

有一组数(a,b,c)

a = p1^i1 * p2^i2 * p3^i3 * ……

b = p1^j1 * p2^j2 * p3^j3 * ……

c = p1^k1 * p2^k2 * p3^k3 * ……

(pi是素数)

他们的G=p1^min(i1,j1,k1)*p2^min(i2,ji2,k2)*...

他们的L=p1^max(i1,j1,k1)*p1^max(i2,j2,k2)*....

令k=L/G;

所以 k=p1^x1*p2^x2...

现在我们可以使a,b,c他们三个都是G,现在要让他们的最小公倍数是L,对于P1来说a,b,c至少一个数数要乘以p1^x1才能保证L中的p1的指数,又要让他们的最大公约数等于G,至少有一个p1的指数不变(即乘以p1^0),另外一个的乘以p1^t1(0<=t1<=x1),就能保证L中P1的指数,以此推类每个Pi都要满足这个条件,所以每个Pi组合数就有C(x1+1,1)*A(3,3)i,又考虑到

ti=0,和ti=xi ,这两种情况排列数中3个所以对于每个pi应该是(3+3)+C(xi+1-2,1)*A(3,3)=6+(x1-1)*6=6*x1,最后各个pi的情况相乘就可以了。

#include<stdio.h>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
ll flag[100000];
ll prime[100000];
ll fa[100000];
ll cnt=0;
void factor(int nn)//得到素数幂指数
{
  int cas=0;
  for(int i=0;i<cnt&&prime[i]*prime[i]<=nn;i++)//关于为什么prime[i]*prime[i]<=nn,如果还有更大的素数,prime[i]*prime[i]>nn(prinme[i]*更大的素数)
  {
    while(nn%prime[i]==0)
    {
      fa[cas]++;
      nn/=prime[i];
    }
    if(fa[cas])
    cas++;
    }
    if(nn>1)
    fa[cas]=1;
}

int main ()
{
  memset(flag,1,sizeof(flag));
  for(int i=2;i<100000;i++)//素数筛,原理是把每个素数的倍数筛出来,从小到大,不过还有更快的筛法,大家可以去网上搜一搜
  {
    if(flag)
    {
      for (int j=i+i;j<100000;j+=i)
      {
        flag[j]=0;
      }
    }
  }
  memset(prime,0,sizeof(prime));
  for(int i=2;i<100000;i++)
  {
    if(flag)
    {
      prime[cnt++]=i;
    }
  }
  ll t,g,l;
  scanf("%lld",&t);
  while (t--)
  {  
    memset(fa,0,sizeof(fa));
    scanf("%lld %lld",&g,&l);

    ll k=l/g;

    if(l%g!=0)
    {
      printf("0\n");
      continue;
    }
    factor(k);
    ll sum=1;
    for(int i=0;;i++)
    {
      if(!fa[i])
      {
        break;
      }
      sum*=fa[i];
      sum*=6;
    }
  printf("%d\n",sum);
  }
  return 0;

}

时间: 2024-10-18 12:26:21

HDU 4497 素数筛,合数分解的相关文章

hdu 5428 The Factor(素数筛选合数分解)

题意:求一串数乘积的因子中的最小合数: 思路:比赛时枚举因子,枚举到两个时结束,估计超时,结果果然被叉了: 将每个数分解,取最小的两个质因子,若数目少于2,则不存在: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; int t,n,m; int num[505]; const int MAXN=100000; int pr

HDU 1016 Prime Ring Problem (素数筛+DFS)

题目链接 题意 : 就是把n个数安排在环上,要求每两个相邻的数之和一定是素数,第一个数一定是1.输出所有可能的排列. 思路 : 先打个素数表.然后循环去搜..... 1 //1016 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 6 using namespace std ; 7 8 bool vis[21]; 9 int prime[42] ,cs[21]; 10 int n ; 11

hdu 5317 合数分解+预处理

RGCDQ Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2818    Accepted Submission(s): 1108 Problem Description Mr. Hdu is interested in Greatest Common Divisor (GCD). He wants to find more and m

HDU 5317 RGCDQ (合数分解+预处理)

题目链接:HDU 5317 RGCDQ 题意:定义函数F(x)为x的不同的素因子且小于等于x的个数,询问[l,r]区间中gcd(F(i),F(j))的最大值. 思路:暴力预处理出所有的合数分解结果,发现F(x)最大也只有7,之后就是暴力求出所有1到7出现次数的前缀和.询问的时候就打到O(1)了. AC代码: #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #

poj 2689 Prime Distance(筛一个区间内的素数(或合数))

: [题意说明] 给你指定的范围[L, U],在这个范围内找出相邻最近和最远的两组质数,若最近或最远值相同,输出较小的那组.其中:1≤L,另U-L≤1000000. [问题分析] 此题与质数有关,显然若是能求出[L, U]之间的质数,然后从前往后扫描一遍即可出需要的结果,但问题是L与U的范围太大,是不可能在规定的时间内实现的. 但这里给我们提供了另一个条件:U-L≤1000000,如果我们只求1000000以内的素数,完全可以在规定的时间实现的!但由于所求的不是1-1000000以内的素数,所以

hdu_4497GCD and LCM(合数分解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4497 GCD and LCM Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 2151    Accepted Submission(s): 955 Problem Description Given two positive integer

hdu 2012 素数判定 Miller_Rabbin

素数判定 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 71785    Accepted Submission(s): 24969 Problem Description 对于表达式n^2+n+41,当n在(x,y)范围内取整数值时(包括x,y)(-39<=x<y<=50),判定该表达式的值是否都为素数. Input 输入数据

Hdu 4497

题目链接 已知 gcd(x, y, z) = G, lcm(x, y, z) = L, 求有多少种组合(x, y, z)可以满足条件.G, L都在32位int范围内. 思路: 素数分解 + 容斥 L : p1^t1 * p2^t2 ... * pi^ti G: q1^s1 * q2^s2... * qi^si 若 L % G 不为0, 则不存在解; 否则 L分解结果中素因子的长度一定不小于G分解结果的素因子个数, 且对应的素数的指数部分前者(L的分解结果)一定不小于后者(G的分解结果). 比如,

数论线性筛总结 (素数筛,欧拉函数筛,莫比乌斯函数筛,前n个数的约数个数筛)

线性筛 线性筛在数论中起着至关重要的作用,可以大大降低求解一些问题的时间复杂度,使用线性筛有个前提(除了素数筛)所求函数必须是数论上定义的积性函数,即对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数,若a,b不互质也满足的话则称作完全积性函数,下面说明每个筛子是怎么筛的. 最基础的是素数筛,其它三个筛都是以素数筛为前提 素数筛 void get_prime() { int pnum = 0; for(int i = 2;