AcWing200 Hankson的趣味题(数学)

这题我们很容易想到可以先求出x的取值,再进行比对看看是否可以

但是如果我们直接求出所有x的取值复杂度会超,因为求约数的复杂度较高

所以我们考虑先求去所以质因数,再通过dfs来求约数

之后进行比对即可。

#include<iostream>
#include<string>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int primes[N];
int st[N];
int idx;
int cnt;
int div1[N];
int cnt1;
struct node{
    int p,s;
}s[N];
void init(){
    int i;
    for(i=2;i<N;i++){
        if(!st[i]){
            primes[cnt++]=i;
            st[i]=1;
        }
        else{
            int j;
            for(j=0;primes[j]*i<N;j++){
                st[i*primes[j]]=1;
                if(i%primes[j]==0)
                break;
            }
        }
    }
}
int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
void dfs(int u,int p){
    if(u==idx){
        div1[cnt1++]=p;
        return ;
    }
    int i;
    for(i=0;i<=s[u].s;i++){
        dfs(u+1,p);
        p*=s[u].p;
    }
}
int main(){
    int t;
    cin>>t;
    init();
    while(t--){
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        int i;
        int tmp=d;
        idx=0;
        for(i=0;primes[i]<=tmp/primes[i];i++){
            int sign=primes[i];
            if(tmp%sign==0){
                int num=0;
                while(tmp%sign==0){
                    tmp/=sign;
                    num++;
                }
                s[idx++]={sign,num};
            }
        }
        if(tmp>1){
            s[idx++]={tmp,1};
        }
        cnt1=0;
        dfs(0,1);
        int res=0;
        for(i=0;i<cnt1;i++){
            int num=div1[i];
            if(gcd(num,a)==b&&(ll)num*c/gcd(num,c)==d)
             res++;
        }
        cout<<res<<endl;
    }
}
View Code

 

posted @ 2020-03-22 17:49  朝暮不思  阅读(182)  评论(0编辑  收藏  举报