洛谷 P1072 Hankson 的趣味题 —— 质因数分解

题目:https://www.luogu.org/problemnew/show/P1072

满足条件的数 x 一定是 a1 的倍数,b1 的因数,a0/a1 与 x/a1 互质,b1/b0 与 b1/x 互质;

按质因子来看,满足要求的数 x 的某个质因子 pi 的次数应该:

1.大于等于 a1 的,小于等于 b1 的;

2.如果 a0/a1 有 pi 剩余,则 x 的 pi 的次数只能是 a1 的 pi 的次数(无选择余地,不贡献答案);

3.如果 b1/b0 有 pi 剩余,则 x 的 pi 的次数只能是 b1 的 pi 的次数(同上);

然后要注意条件2,3之间可能有冲突,判掉即可。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
typedef long long ll;
int const xn=405;
int n,cnt,p[xn],k[5][xn];
map<int,int>mp;
int rd()
{
  int ret=0,f=1; char ch=getchar();
  while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
  while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
  return f?ret:-ret;
}
void solve(int x,int l)
{
  for(int i=2;i*i<=x;i++)
    {
      if(x%i)continue;
      if(!mp[i])mp[i]=++cnt,p[cnt]=i; int t=mp[i];
      while(x%i==0)k[l][t]++,x/=i;
    }
  if(x==1)return;
  if(!mp[x])mp[x]=++cnt,p[cnt]=x; k[l][mp[x]]=1;
}
int main()
{
  n=rd(); 
  while(n--)
    {
      ll ans=1; bool fl=0; memset(k,0,sizeof k); cnt=0; mp.clear();
      for(int i=0,x;i<4;i++)x=rd(),solve(x,i);
//      printf("cnt=%d\n",cnt);
//      for(int i=1;i<=cnt;i++)
//        {
//          printf("p[%d]=%d:",i,p[i]);
//          for(int j=0;j<4;j++)printf("k[%d]=%d ",j,k[j][i]);
//          printf("\n");
//        }
      for(int i=1;i<=cnt;i++)
        {
          if(k[1][i]>k[3][i]||k[0][i]<k[1][i]||k[3][i]<k[2][i]){fl=1; break;}
          if(k[3][i]!=k[2][i]&&k[0][i]!=k[1][i]&&k[3][i]!=k[1][i])
          {fl=1; break;}//必须有 lcm--i -><-必须有 gcd--i //!!!
          if(k[0][i]!=k[1][i]||k[2][i]!=k[3][i])continue;//则 i 处无选择余地 
          ans=ans*(k[3][i]-k[1][i]+1);
        }
      if(fl)printf("0\n");
      else printf("%lld\n",ans);
    }
  return 0;
}

 

posted @ 2018-10-09 19:04  Zinn  阅读(228)  评论(0编辑  收藏  举报