P1753HackSon的趣味题

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<stdlib.h>
  5 #include<string.h>
  6 #include<math.h>
  7 #include<queue>
  8 using namespace std;
  9 typedef long long LL;
 10 bool prime[200000];
 11 int ans[200000];
 12 LL dns[200000];
 13 LL id[200];
 14 LL d[4][100];
 15 LL ask[10000];
 16 int e[4][10000];
 17 int ck[400];
 18 queue<LL>que;
 19 int main(void)
 20 {
 21     int i,j,k;
 22     LL n,n1,m,m1;
 23     for(i=2; i<=2000; i++)
 24     {
 25         if(!prime[i])
 26         {
 27             for(j=i; i*j<=200000; j++)
 28             {
 29                 prime[i*j]=true;
 30             }
 31         }
 32     }
 33     int cnt=0;
 34     for(i=2; i<=200000; i++)
 35     {
 36         if(!prime[i])
 37         {
 38             ans[cnt++]=i;
 39         }
 40     }
 41     scanf("%d",&k);
 42     int s;
 43     for(s=0; s<k; s++)
 44     {
 45         memset(d,0,sizeof(d));
 46         memset(e,0,sizeof(e));
 47         for(i=0; i<4; i++)
 48             cin>>id[i];
 49         for(i=0; i<4; i++)
 50         {
 51             LL kk=id[i];
 52             int ak=0;
 53             int cc=0;
 54             while(kk>1&&ak<cnt)
 55             {
 56                 if(ans[ak]*ans[ak]>kk)
 57                     break;
 58                 else if(kk%ans[ak]==0)
 59                 {
 60                     que.push(ans[ak]);
 61                     d[i][cc++]=ans[ak];
 62                     kk/=ans[ak];
 63                 }
 64                 else
 65                 {
 66                     ak++;
 67                 }
 68             }
 69             if(kk>1)
 70             {
 71                 que.push(kk);
 72                 d[i][cc++]=kk;
 73             }
 74         }
 75         int cc=0;
 76         while(!que.empty())
 77         {
 78             ask[cc++]=que.front();
 79             que.pop();
 80         }
 81         sort(ask,ask+cc);
 82         for(i=0; i<4; i++)
 83         {
 84             for(j=0; d[i][j]!=0; j++)
 85             {
 86                 int l=0;
 87                 int r=cc-1;
 88                 int ff;
 89                 while(l<=r)
 90                 {
 91                     int mid=(l+r)/2;
 92                     if(ask[mid]>=d[i][j])
 93                     {
 94                         ff=mid;
 95                         r=mid-1;
 96                     }
 97                     else l=mid+1;
 98                 }
 99                 d[i][j]=ff;
100                 e[i][ff]++;
101             }
102         }
103         LL as=1;
104         for(i=0; i<400; i++)
105         {
106             int pp=0;
107             for(j=0; j<4; j++)
108             {
109                 pp+=e[j][i];
110             }
111             if(pp==0)
112                 ck[i]=1;
113             else
114             {
115                 if(e[0][i]>e[1][i])
116                 {
117                     if(e[2][i]<e[3][i]&&e[1][i]<e[3][i])
118                     {
119                         ck[i]=0;
120                     }
121                     else
122                         ck[i]=1;
123                 }
124                 if(e[0][i]==e[1][i])
125                 {   if(e[2][i]==e[3][i])
126                     {int xx=e[3][i]-e[0][i]+1;
127                     if(xx<=0)
128                         xx=0;
129                     ck[i]=xx;}
130                     else
131                     {
132                         if(e[1][i]>e[3][i])
133                             ck[i]=0;
134                         else ck[i]=1;
135                     }
136                 }
137             }
138         }
139         for(i=0; i<400; i++)
140         {
141             as*=ck[i];
142         }
143         printf("%lld
",as);
144     }
145     return 0;
146 }

描述

Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫 Hankson。现
在,刚刚放学回家的 Hankson 正在思考一个有趣的问题。
今天在课堂上,老师讲解了如何求两个正整数 c1和 c2 的最大公约数和最小公倍数。现
在 Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公
倍数”之类问题的“逆问题” ,这个问题是这样的:已知正整数 a0,a1,b0,b1,设某未知正整
数 x 满足:
1. x 和 a0 的最大公约数是 a1;
2. x 和b0 的最小公倍数是 b1。
Hankson 的“逆问题”就是求出满足条件的正整数 x。但稍加思索之后,他发现这样的
x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮
助他编程求解这个问题。

格式

输入格式

第一行为一个正整数 n,表示有 n 组输入数据。接下来的 n 行每
行一组输入数据,为四个正整数 a0,a1,b0,b1,每两个整数之间用一个空格隔开。输入
数据保证 a0能被 a1 整除,b1 能被 b0整除。

输出格式

共n 行。每组输入数据的输出结果占一行,为一个整数。
对于每组数据:若不存在这样的 x,请输出 0;
若存在这样的 x,请输出满足条件的 x 的个数;

样例1

样例输入1[复制]

2 
41 1 96 288 
95 1 37 1776 

样例输出1[复制]

6 
2 

限制

每个测试点1s

来源

NOIP 2009

思路:先打表求质数;然后我们知道

最大公约数:=x1min(c1,cc2)*....xnmin(cn,ccn);

最小公倍数:=x1max(c1,cc2)*.....xnmax(cn,ccn)

这样我们分别分解上面给的四个数;

然后分别判断X的各个质因数的个数可以取多少种,然后乘法原理算方案;

油!油!you@
原文地址:https://www.cnblogs.com/zzuli2sjy/p/5487798.html