loj2589 「NOIP2009」Hankson 的趣味题

对于质因数分解理解还不到位。

此题可知$lcm$是$x$的倍数,$x$是$lcm$的约数,只要在$lcm$的分解质因数里对每一个质因子讨论种数即可。

具体来说,对于$lcm$的一个质因子$p$,讨论$a,b,c,d(也就是lcm)$关于$p$的幂次,然后比较大小,分类讨论得出种数。

实现上来看,只要在枚举$lcm$质因子过程中,一带把$a,b,c,d$全部除去这个因子,再比较幂次。

一些细节:

  • 一定要保证$b|d$,不解释。
  • 可能$a$包含$lcm$没有的质因子,但不影响讨论。
  • 枚举$1 \sim \sqrt{lcm}$来找$lcm$质因子,通过优化,只枚举$1 \sim \sqrt{lcm}$内质数(可预处理)可以降低复杂度。
  • 注意最后讨论有没有剩下的一个超过$\sqrt{lcm}$的质因子。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define dbg(x) cerr << #x << " = " << x <<endl
 7 using namespace std;
 8 typedef long long ll;
 9 typedef double db;
10 typedef pair<int,int> pii;
11 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
12 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
16 template<typename T>inline T read(T&x){
17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
19 }
20 const int N=44721;
21 int prime[N],inshi[N+3],n;
22 ll ans=1;
23 int T,a,b,c,d,t1,t2,t3,t4,fl;
24 inline void preprocess(){
25     for(register int i=2;i<=N;++i){
26         if(!inshi[i])prime[++n]=i;
27         for(register int j=1;j<=n&&prime[j]<=N/i;++j){
28             inshi[i*prime[j]]=prime[j];
29             if(inshi[i]==prime[j])break;
30         }
31     }
32 }
33 
34 int main(){//freopen("son10.in","r",stdin);freopen("test.out","w",stdout);
35     preprocess();
36     read(T);while(T--){
37         read(a),read(b),read(c),read(d);
38         if(d%b){puts("0");continue;}
39         ans=1,fl=0;
40         for(register int i=1;prime[i]*prime[i]<=d;++i)if(d%prime[i]==0){
41             t1=t2=t3=t4=0;
42             while(d%prime[i]==0)d/=prime[i],++t4;
43             while(c%prime[i]==0)c/=prime[i],++t3;
44             while(b%prime[i]==0)b/=prime[i],++t2;
45             while(a%prime[i]==0)a/=prime[i],++t1;
46             if(t1==t2&&t3==t4&&t2<=t3)ans*=(t3-t2+1);
47             else if(!(t1==t2&&t3<t4&&t2<=t4)&&!(t3==t4&&t1>t2&&t2<=t4)&&!(t1>t2&&t3<t4&&t2==t4)){fl=1;break;}
48         }
49         if(!fl&&d^1){
50             t4=1,t3=c^1?1:0,t2=b^1?1:0,t1=a%d==0?1:0;
51             if(t1==t2&&t3==t4&&t2<=t3)ans*=(t3-t2+1);
52             else if(!(t1==t2&&t3<t4&&t2<=t4)&&!(t3==t4&&t1>t2&&t2<=t4)&&!(t1>t2&&t3<t4&&t2==t4))fl=1;
53         }
54         if(fl)puts("0");
55         else printf("%d\n",ans);
56     }
57     return 0;
58 }
View Code
posted @ 2019-09-06 10:33  Ametsuji_akiya  阅读(155)  评论(0编辑  收藏  举报