luogu P1072 $Hankson$ 的趣味题

这里提供两种做法

sol 1

考虑两个数\(A,B\)\(C=gcd(A,B),D=lcm(A,B)\)的关系

\(S=\{2,3,5...P_n\}\)为质数集合\(p_{x,i}\)表示\(x\)的第\(i\)种质因子数量

显然\(p_{C,i}=min(p_{A,i},p_{B,i}),p_{D,i}=max(p_{A,i},p_{B,i})\)

所以对于每种质因子,考虑在\(a_0,a_1,b_0,b_1\)的出现次数,这里分别记为\(o_1,o_2,o_3,o_4\)

以下几种情况无解
1.\(o_1<o_2\)\(o_3>o_4\) (推出的结论)
2.\(o_1=o_2\)\(o_3=o_4\)\(o_1>o_3\) (答案这一种质因子数量取值范围\([o_1,o_3]\))
3.\(o_1>o_2\)\(o_3<o_4\)\(o_2\ne o_4\) (答案这一种质因子数量是\(o_2\),也是\(o_4\))

其他情况下,对于每一种质因子,\(ans*=(o_3-o_1+1)\)

代码被吞了qwq 其实本来就没有

sol 2

考虑枚举答案

答案显然是\(b_1\)的因数,所以只要枚举\(i\)\(1\)\(\sqrt{b_1}\),判断\(i\)\(b_1-i\)救星了

注意\(i=b_1-i\)的情况

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#define LL long long
#define il inline
#define re register

using namespace std;
const LL mod=1000000007;
il LL rd()
{
    re LL x=0,w=1;re char ch;
    while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*w;
}
int prm[5010],pp[50010],tt;
il LL gcd(LL a,LL b)
{
  LL tm;
  while(b){tm=a,a=b,b=tm%b;}
  return a;
}
il LL lcm(LL a,LL b)
{
  return a*b/gcd(a,b);
}

int main()
{
  for(int i=2;i<=45000;i++)
    {
      if(!pp[i]) pp[i]=i,prm[++tt]=i;
      for(int j=1;j<=tt&&i*prm[j]<=45000;j++)
        {
          pp[i*prm[j]]=prm[j];
          if(i%prm[j]==0) break;
        }
    }
  int q=rd();
  while(q--)
    {
      int a0=rd(),a1=rd(),b0=rd(),b1=rd(),sq=sqrt(b1),ans=0;
      for(int i=1;i<=sq;i++)
        {
          if(b1%i) continue;
          if(gcd(i,a0)==a1&&lcm(i,b0)==b1) ++ans;
          if(i*i==b1) continue;
          if(gcd(b1/i,a0)==a1&&lcm(b1/i,b0)==b1) ++ans;
        }
      printf("%d\n",ans);
    }
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/smyjr/p/9403568.html
今日推荐