一个JSB做法
由$frac{x*b0}{gcd(x,b0)}=b1$,可得$frac{x}{gcd(x,b0)}=frac{b1}{b0}$
设$b2=frac{b1}{b0}$
所以对$b2$和$b0$分解质因数,可以得到结论:
1.x必须包含b2中所有的质因数,且个数等于它在b2和b0(如果b0中有的话)中的数量和
2.对于b0中有但b2中没有的质因数,x中它的个数可以是[0,b0中的个数]
然后关于a0和a1,也有结论:
1.x中必须包含a1中的所有质因数
2.x中不能包含a0中的、a1以外的(在数量和种类方面)质因数
然后就可以开始乱搞了
首先打出1e5以内的素数,然后拿着它们分解质因数(因为我只需要做到$sqrt{N}$)。注意一个数如果最后剩下不是1,那么剩下这个数也是个质因数(大于$sqrt{N}$)
然后把这些存到set里,按照上面的规则乱搞......
一个数最多大概也就十几种质因数,所以复杂度没什么问题。
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define IT set<pa>::iterator 4 #define CLR(a,x) memset(a,x,sizeof(a)) 5 using namespace std; 6 typedef long long ll; 7 const int maxn=1e5+10,inf=2e9+1; 8 9 inline ll rd(){ 10 ll x=0;char c=getchar();int neg=1; 11 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 12 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 13 return x*neg; 14 } 15 16 bool ispri[maxn]; 17 int pri[maxn],pct; 18 set<pa> g[5]; 19 20 inline void get(int id,int x){ 21 g[id].clear(); 22 for(int i=1;x>1&&i<=pct;i++){ 23 if(x<pri[i]) break; 24 if(x%pri[i]) continue; 25 int cnt=0; 26 while(x%pri[i]==0) x/=pri[i],cnt++; 27 g[id].insert(make_pair(pri[i],cnt)); 28 } 29 if(x!=1) g[id].insert(make_pair(x,1)); 30 31 } 32 33 int main(){ 34 int i,j; 35 int N=rd(); 36 CLR(ispri,1);ispri[0]=ispri[1]=0; 37 for(i=2;i<=100000;i++){ 38 if(ispri[i]){ 39 for(j=i+i;j<=100000;j+=i){ 40 ispri[j]=0; 41 } 42 } 43 }for(i=2,j=0;i<=100000;i++) if(ispri[i]) pri[++pct]=i; 44 for(i=1;i<=N;i++){ 45 int a1=rd(),a2=rd(),b1=rd(),b2=rd(); 46 int b3=b2/b1; 47 get(0,a1);get(1,a2);get(2,b1);get(3,b3); 48 g[4].clear(); 49 for(IT it=g[0].begin();it!=g[0].end();it++){ 50 IT it2=g[1].lower_bound(make_pair(it->first,-1)); 51 if(it2->first!=it->first) g[4].insert(make_pair(it->first,0)); 52 else if(it2->second!=it->second) g[4].insert(make_pair(it->first,it2->second)); 53 else g[4].insert(make_pair(it->first,-it2->second)); 54 } 55 int ans=1; 56 for(IT it=g[4].begin();it!=g[4].end();it++){ 57 IT it2=g[2].lower_bound(make_pair(it->first,-inf)); 58 IT it3=g[3].lower_bound(make_pair(it->first,-inf)); 59 if(it->second&&it2->first!=it->first&&it3->first!=it->first) ans=0; 60 if(it->first==it3->first&&it2->first!=it->first&&((it->second>=0&&it3->second!=it->second)||(it->second<0&&(-it->second)>it3->second))) ans=0; 61 } 62 if(!ans) {printf("0 ");continue;} 63 for(IT it=g[2].begin();it!=g[2].end()&&ans;it++){ 64 IT it2=g[3].lower_bound(make_pair(it->first,-inf)); 65 IT it3=g[4].lower_bound(make_pair(it->first,-inf)); 66 if(it2->first!=it->first){ 67 if(it3->first!=it->first) ans*=it->second+1; 68 else if(abs(it3->second)>it->second) ans=0; 69 else if(it3->second<0) ans*=it->second+it3->second+1; 70 }else{ 71 if(it3->first!=it->first); 72 else if(it3->second>=0&&it3->second!=it2->second+it->second) ans=0; 73 else if(it3->second<0&&it2->second+it->second<-it3->second) ans=0; 74 } 75 } 76 printf("%d ",ans); 77 } 78 return 0; 79 }