码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4497 素数筛,合数分解

时间:2016-08-02 21:00:29      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:

题意:给你两个数,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;

}

 

HDU 4497 素数筛,合数分解

标签:

原文地址:http://www.cnblogs.com/MasNoon/p/5730575.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!