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 }