1. 程式人生 > >luogu1072 [NOIp2009]Hankson的趣味題 (數學+STL::set)

luogu1072 [NOIp2009]Hankson的趣味題 (數學+STL::set)

turn 不能 clear its printf 等於 cond 如果 包含

一個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\n");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\n",ans); 77 } 78 return 0; 79 }

luogu1072 [NOIp2009]Hankson的趣味題 (數學+STL::set)