zoukankan      html  css  js  c++  java
  • GCD&LCM

    1.青蛙的约会

    题目:http://poj.org/problem?id=1061

    题解:(x+mt)%L==(y+nt)%L等价于x-y+(m-n)t=kL

    因此我们整理一下:(m-n)t+kL=y-x

    a=m-n,b=L,c=y-x

    在这里需要注意a的值不为负,如果为负,则a=-a,c=-c

    然后套用公式求出最小的t:t=(c/g*x%(b/g)+b/g)%(b/g)

    代码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    typedef long long ll;
    
    ll extend_gcd(ll a,ll b,ll &x,ll &y)
    {
        if(b==0)
        {
            x=1,y=0;
            return a;
        }
        ll res=extend_gcd(b,a%b,x,y);
        ll tmp=x;
        x=y;
        y=tmp-(a/b)*y;
        return res;
    }
    
    int main()
    {
        ll i,j,x,y,m,n,l,a,b,c;
        cin>>x>>y>>m>>n>>l;
        a=m-n;b=l;c=y-x;
        if(a<0)
        {
            a=-a;
            c=-c;
        }
        ll g=extend_gcd(a,b,x,y);
        if(c%g!=0)
        {
            puts("Impossible");
        }
        else
        {
            cout<<(c/g*x%(b/g)+b/g)%(b/g)<<endl;
        }
        return 0;
    }

    2.Least Common Multiple

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1019

    题解:每两个之间求一遍lcm,一共球n次

    代码:

    #include<iostream>
    using namespace std;
    typedef long long ll;
    ll t,a[100000],n;
    ll gcd(ll a,ll b)
    {
        return b==0?a:gcd(b,a%b);
    }
    ll lcm(ll a,ll b)
    {
        return a*b/gcd(a,b);
    }
    
    int main()
    {
        ll i,j;
        cin>>t;
        while(t--)
        {
            cin>>n;
            for(i=0;i<n;i++)
                cin>>a[i];
            ll res=a[0];
            for(i=1;i<n;i++)
            {
                res=lcm(res,a[i]);
            }
            cout<<res<<endl;
        }
        return 0;
    }

    3. A/B

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1576

    题解:逆元的应用

    代码:

    #include<iostream>
    using namespace std;
    typedef long long ll;
    ll extend_gcd(ll a,ll b,ll& x,ll& y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        ll res=extend_gcd(b,a%b,x,y);
        ll tmp=x;
        x=y;
        y=tmp-(a/b)*y;
    }
    
    ll mod_inverse(ll a,ll m)
    {
        ll x,y;
        extend_gcd(a,m,x,y);
        return (m+x%m)%m;
    }
    
    int main()
    {
        ll i,j,t,n,b;
        ll mod=9973;
        cin>>t;
        while(t--)
        {
            cin>>n>>b;
            cout<<(n*mod_inverse(b,mod))%9973<<endl;
        }
        return 0;
    }

    4.又见GCD

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2504

    题解:a和c的最大公约数为b,因此c的选取从2*b开始,与a计算gcd,如果不是b就加b,如此往复

    代码:

    #include<iostream>
    using namespace std;
    
    int gcd(int a,int b)
    {
        return b==0?a:gcd(b,a%b);
    }
    
    int main()
    {
        int i,j,n,a,b,c;
        cin>>n;
        while(n--)
        {
            cin>>a>>b;
            c=b*2;
            while(gcd(a,c)!=b)
            {
                c+=b;
            }
            cout<<c<<endl;
        }
        return 0;
    }

    5.GCD

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2588

    题解:

    给定N,M求gcd(i,N)>=M的i的个数

    我们可以分解N=a*b, i=a*d(b>=d 且b,d互质),那么我们要求的就是a》=m的时候d的个数(b随a而确定)

    由于b>=d且b,d互质,所以这个数目就是φ(b)-1  

    但是,如果对于每个a枚举b,铁定超时。(仍然O((N-M)*sqrt(N))的复杂度)

    但是如果单纯这样全部枚举的话依旧会超时,所以我们要想一个办法去优化它。

    我们可以折半枚举,这里的折半并不是二分的意思。

    我们先看,我们枚举时,当i<sqrt(n),假设a=n / i, 当i>sqrt(n)之后 有b=n/i,我们观察到当n%i==0时,会出现一种情况,就是a*b==n。所以我们就可以只需要枚举sqrt(n)种情况,然后和它对应的情况就是 n/i。

    我们这种枚举时间会快非常多

    代码:

    #include<iostream>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    ll phi(ll n)
    {
        ll ans=n;
        for(ll i=2;i<=sqrt(n);i++)
        {
            if(n%i==0)
            {
                ans=ans/i*(i-1);
                while(n%i==0)
                    n/=i;
            }
        }
        if(n>1)
            ans=ans/n*(n-1);
        return ans;
    }
    int main()
    {
        int t;
        ll n,m;
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            ll ans=0;
            for(ll i=1;i*i<=n;i++)
            {
                if(n%i==0)
                {
                    if(i>=m)
                        ans+=phi(n/i);//计算sqrt(n)左边的
                    if(i*i!=n&&n/i>=m)
                        ans+=phi(i);//计算计算sqrt(n)右边的i*i==n时,在上个语句已经执行 (避免)完全平方算两次
                }
            }
            cout<<ans<<endl;
        }
        return 0;
    }

    6.GCD

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5223

    题解:这个从体面理解是要求满足区间的最小数和,我们满足当前区间的最大公约数,就是使当前区间全都为最大公约数,这样总和最小,但是会涉及到区间重叠的部分,因此那一部分就要取:当前的数于区间的最大公约数的最小公倍数,然后都弄完后,进行检验,是否该区间上的数的最大公约数为ans,然后输出即可。

    代码:

    #include<iostream>
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b)
    {
        return b==0?a:gcd(b,a%b);
    }
    ll num[1010],l[1010],r[1010],ans[1010];
    int main()
    {
        ll t,i,j,n,q;
        cin>>t;
        while(t--)
        {
            cin>>n>>q;
            for(i=1;i<=n;i++)
                num[i]=1;
            for(i=0;i<q;i++)
            {
                cin>>l[i]>>r[i]>>ans[i];
                for(j=l[i];j<=r[i];j++)
                    num[j]=num[j]*ans[i]/gcd(num[j],ans[i]);
            }
            bool falg=true;
            for(i=0;i<q;i++)
            {
                ll cur=num[l[i]];
                for(j=l[i]+1;j<=r[i];j++)
                    cur=gcd(cur,num[j]);
                if(cur!=ans[i])
                {
                    falg=false;
                    break;
                }
            }
            if(falg==true)
            {
                for(i=1;i<=n;i++)
                {
                    cout<<num[i];
                    if(i!=n)
                        cout<<" ";
                }
                cout<<endl;
            }
            else
            {
                cout<<"Stupid BrotherK!"<<endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    使用java的wsimport.exe生成wsdl的客户端代码【转】
    css 动画【转】
    如何让javascript base64加密后不含+/=
    UEditor js动态创建和textarea中渲染【原】
    在js或jquery中动态添加js脚本【转】
    利用spring的MultipartFile实现文件上传【原】
    hibernate状态转换关系图【原】
    ssh框架里拦截器的权限验证基本思路【转】
    JAVA中三种URL连接方法
    程序出错问题总结
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/13196021.html
Copyright © 2011-2022 走看看