hdu5019 Revenge of GCD(找第大GCD)

题意:
找到两个数 x , y x,y 的第 k k 大公约数。
思路:
先求出最大公约数,然后分解因子。很显然,最大公约数的因子组成 x , y x,y 的全部公约数,然后用快排在 O ( n ) O(n) 时间求第 k k 大公约数即可。
A C   C o d e : AC \ Code:

#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#include<cmath>
#include<set>
#include<stack>
#include<cstdio>
#include<sstream>
#include<vector>
#include<bitset>
#include<algorithm>
#include<unordered_map>
using namespace std;
#define read(x) scanf("%d",&x)
#define Read(x,y) scanf("%d%d",&x,&y)
#define gc(x)  scanf(" %c",&x);
#define mmt(x,y)  memset(x,y,sizeof x)
#define write(x) printf("%d\n",x)
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define ll long long
const int N = 100000 + 100;
const int M = 3e6 + 1005;
typedef long long LL;
ll gcd(ll a,ll b){
    if(b) return gcd(b,a%b);
    else return a;
}
ll prim[N];
ll  Pos(ll a[],ll l,ll r){
    a[0] = a[l];
    while(l < r){
        while(l < r&&a[0] >= a[r]) r -- ;
        if(l < r){
            a[l] = a[r];
            l ++;
        }
        while(l < r&&a[0] <= a[l]) l++;
        if(l < r){
            a[r] = a[l];
            r --;
        }
    }
    a[l] = a[0] ;
    return l;
}
void Qsort(ll a[],ll l,ll r,ll k){
    if(l < r){
        int pos = Pos(a,l,r);
        if(pos>k) Qsort(a,l,pos-1,k);
        else if(pos<k) Qsort(a,pos+1,r,k);
    }
}
int main(){
    int t;
    cin>>t;
    while(t--){
        ll a,b,c;
        cin>>a>>b>>c;
        ll m = gcd(a,b);
        ll tot = 0;
        for(ll i = 1;i <= sqrt(m);++i){
            if(m%i == 0){
                prim[++tot] = i;
                if(m / i != i) prim[++tot] = m / i;
            }
        }
        if(tot < c) {puts("-1");continue;}
        Qsort(prim,1,tot,c);
        printf("%lld\n",prim[c]);
    }
}
发布了632 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_43408238/article/details/103639529