题目链接:https://www.luogu.com.cn/problem/P1072
更高效:
预处理的质数中从2~$\sqrt(d)$,检查每一个质数是不是d的约数,如果是,按上述方法计算$cnt_p$。如果d不能被上述所有的质数整除,则说明d本身是质数,应该计算$cnt_d$。
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 using namespace std; 4 const int N=100006; 5 const int M=50005; 6 int vis[N],p[N]; 7 int n,cnt,ans,ma,mb,mc,md; 8 int a,b,c,d; 9 void is_prime(){ 10 for(int i=2;i<=M;i++){ 11 if(!vis[i]) p[++cnt]=i; 12 for(int j=1;j<=cnt;j++){ 13 if(i*p[j]>M) break; 14 vis[i*p[j]]=1; 15 if(i%p[j]==0) break; 16 } 17 } 18 } 19 int get(int &x,int y){ 20 int sum=0; 21 while(x%y==0) x/=y,sum++; 22 return sum; 23 } 24 int calc(int x){ 25 int sum=0; 26 int ma=get(a,x),mb=get(b,x),mc=get(c,x),md=get(d,x); 27 if(ma==mc&&mb==md&&mc<=md) sum=md-mc+1; 28 else if(ma>mc&&mb==md&&mc<=md) sum=1; 29 else if(ma==mc&&mb<md&&mc<=md) sum=1; 30 else if(ma>mc&&mb<md&&mc==md) sum=1; 31 return sum; 32 } 33 int main(){ 34 scanf("%d",&n); 35 is_prime(); 36 while(n--){ 37 ans=1; 38 scanf("%d%d%d%d",&a,&c,&b,&d); 39 for(int i=1;i<=cnt&&p[i]*p[i]<=d;i++) 40 if(d%p[i]==0) ans*=calc(p[i]); 41 if(d>1) ans*=calc(d); 42 printf("%d\n",ans); 43 } 44 return 0; 45 }AC代码