1. 程式人生 > 實用技巧 >2020牛客多校第三場F題Fraction Construction Problem(擴充套件歐幾里得數論)

2020牛客多校第三場F題Fraction Construction Problem(擴充套件歐幾里得數論)

題目連結:https://ac.nowcoder.com/acm/contest/5668/F

題意:輸入a,b構造分數等式成立

題解:分類討論

第一種是分子分母不是最簡,那麼也就是說a,b存在一個公因子,同時也說明了b不是一個質數。

第二種情況,分子分母最簡了,但分母b的不相同的質因子不超過一個,那麼無解。無法分解b

第三種情況,分子分母最簡了,但分母的不相同的質因子超過一個。擴充套件歐幾里得。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int mac=2e6+10;

int min_prim[mac],prim_num[mac];
int vis[mac]; void init() { int m=sqrt(mac); for (int i=2; i<m; i++){ if (!vis[i]){ min_prim[i]=i; for (int j=i*i; j<mac; j+=i){ vis[j]=1; if (!min_prim[j]) min_prim[j]=i;//找到每個數的最小質因子 } } } for (int
i=1; i<mac; i++){ if (!vis[i]) continue; prim_num[i]++; int x=i; while (x%min_prim[i]==0) x/=min_prim[i]; if (x!=1) prim_num[i]++;//判斷是否有兩個互異的質因子 } } ll exgcd(ll a,ll b,ll &x,ll &y) { if (!b) { x=1; y=0; return a; } ll d
=exgcd(b,a%b,y,x); y-=a/b*x; return d; } int main(int argc, char const *argv[]) { int t; init(); scanf ("%d",&t); while (t--){ int a,b; scanf ("%d%d",&a,&b); int g=__gcd(a,b); if (g!=1) { printf("%d %d %d %d\n",a/g+1,b/g,1,b/g); continue; } if (prim_num[b]<=1) {printf("-1 -1 -1 -1\n"); continue;} ll d=1,f=b; while (f%min_prim[b]==0) { f/=min_prim[b]; d*=min_prim[b]; } ll c,e; exgcd(f,d,c,e); e=-e; while (e<0 || c<0) e+=f,c+=d; printf ("%lld %lld %lld %lld\n",1LL*c*a,d,1LL*e*a,f); } return 0; }