博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 4497 素数筛,合数分解
阅读量:4467 次
发布时间:2019-06-08

本文共 2056 字,大约阅读时间需要 6 分钟。

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

}

 

转载于:https://www.cnblogs.com/MasNoon/p/5730575.html

你可能感兴趣的文章
Jsp通过JDBC连接到SQL Server2008数据库遇到的几个问题
查看>>
idea 不能编译生成class文件
查看>>
javascript原生百叶窗
查看>>
单播组播和广播
查看>>
JSPatch - iOS 动态补丁
查看>>
eclipse设置和优化
查看>>
WinFrom玩转config配置文件
查看>>
IIS服务中五种身份验证
查看>>
c#网络编程-第一章
查看>>
paip.提升效率--僵尸代码的迷思
查看>>
Atitit 自动化gui 与 发帖机 技术
查看>>
Atitit.研发团队与公司绩效管理的原理概论的attilax总结
查看>>
编程模式之装饰模式(Decorator)
查看>>
MVC中关于 使用后台代码 检查 用户名是否已经被清册
查看>>
匿名函数
查看>>
nginx相关
查看>>
(各个公司面试原题)在线做了一套CC++综合測试题,也来測一下你的水平吧(二)...
查看>>
多种选择(Switch)
查看>>
[设计模式] .NET设计模式笔记 - 有多少种设计模式
查看>>
笔记52 Mybatis快速入门(三)
查看>>