• 2020牛客多校三 F-Fraction Construction Problem (欧几里得+构造)


    题目链接:传送门


    思路:

    1.考虑 a b 不互质,即 r=gcd(a,b)>1 ;那么可以构造出 c=(a/r)+1 d=b/r e=1 f=b/r (要求d<b && f<b ,因此 r 必须大于1)

    2.考虑 a b 互质,即 r=gcd(a,b)=1; 那么可以得到式子 (cf-ed)/df = a/b ,可以令d*f = b, 那么可以根据b的值构造出d f,然后解不定方程 cf - ed = a ,其中 a d f 是已知系数;

     根据不定方程可知 gcd(d,f) = 1 ,因为a与b互质,那么肯定a与gcd(d,f) 互质 ,a%1=0;  所以必须要构造出互质d f,这样就必须要求b有两个及以上的质因子个数。  

    其余情况无解。

    #include<bits/stdc++.h>
    /*
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<vector>
    #include<cctype>
    #include<queue>
    #include<algorithm>
    #include<map>
    #include<set>
    */
    #pragma GCC optimize(2)
    using namespace std;
    typedef long long LL;
    typedef unsigned long long uLL;
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pLL;
    typedef pair<double,double> pdd;
    const int N=2e6+5;
    const int M=8e5+5;
    const int inf=0x3f3f3f3f;
    const LL mod=1e9+7;
    const double eps=1e-5;
    const long double pi=acos(-1.0L);
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define fi first
    #define se second
    #define pb push_back
    #define eb emplace_back
    #define mk make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    LL read()
    {
        LL x=0,t=1;
        char ch;
        while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
        while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
        return x*t;
    }
    int cnt[N],num[N];
    int gcd(int x,int y)
    {
        return y==0?x:gcd(y,x%y);
    }
    int exgcd(int a,int b,LL &x,LL &y)
    {
        //printf("...
    ");
        if(b==0)
        {
            x=1; y=0;
            return a;
        }
        LL x1,y1;
        int t=exgcd(b,a%b,x1,y1);
        x=y1;
        y=x1-a/b*y1;
        return t;
    }
    void init()
    {
        for(int i=2;i*i<N;i++)
        {
            if(num[i]) continue;
            num[i]=i;
            for(int j=i*i;j<N;j+=i)
            {
                if(num[j]) continue;
                num[j]=i;
                cnt[j]++;
                int t=j;
                while(t%i==0) t/=i;
                if(t>1) cnt[j]++;
            }
        }
    }
    int main()
    {
        init();
        //for(int i=25;i<=30;i++) printf("..%d %d
    ",num[i],cnt[i]);
        int T=read();
        while(T--)
        {
            int a=read(),b=read();
            int r=gcd(a,b);
            //printf("r = %d
    ",r);
            if(r>1)
            {
                printf("%d %d %d %d
    ",a/r+1,b/r,1,b/r);
                continue;
            }
            if(cnt[b]<2)
            {
                printf("-1 -1 -1 -1
    ");
                continue;
            }
            LL d=1,f=b;
            while(f%num[b]==0) f/=num[b];
            d=b/f;
            LL x,y;
            exgcd(f,d,x,y);
            //printf("%d %d")
            y=-y;
            while(x<=0||y<=0) x+=d,y+=f;//x 是和"b"相关的,这里的b指的就是d;
            printf("%lld %lld %lld %lld
    ",x*a,d,y*a,f);
        }
    }
    View Code
  • 相关阅读:
    Search Insert Position
    Substring with Concatenation of All Words
    Swap Nodes in Pairs
    Remove Element
    Remove Duplicates from Sorted Array
    Letter Combinations of a Phone Number
    Remove Nth Node From End of List
    Valid Parentheses
    Merge k Sorted Lists
    Using an Interface as a Type
  • 原文地址:https://www.cnblogs.com/DeepJay/p/13648047.html
Copyright © 2020-2023  润新知