zoukankan      html  css  js  c++  java
  • 2014.11.12模拟赛【最小公倍数】| vijos1047最小公倍数

     

    最小公倍数(lcm.c/.cpp/.pas)

    题目描述

        给定两个正整数,求他们的最小公倍数。

    样例输入

    28 12

    样例输出

    84

    数据范围

    对于40%数据:1<=a,b<=10^9

    对于60%的数据:1<=a,b<=10^12

    对于100%数据:1<=a,b<=10^100

    提示:为了略微降低题目难度,增加以下条件:

    1. 输入数据保证a>=b

    2. 输入数据保证a、b没有前导0

    3. 输入数据保证除了在两个正整数a、b之间的空格和行末换行符以外,不存在其他非数字字符

    最后友情提醒:高精除高精写二分做法风味更佳

    其实就是superlcm啦……

    先算出gcd(a,b),然后lcm(a,b)=a*b/gcd(a,b)

    40分是暴力,60分lcm(a,b)=a/gcd(a,b)*b,这样不会爆long long

    100分就呵呵了,你只要写高精度减法、乘法、除法就好了

    给现场怒写高精度还A了的hzwer跪了

    这其实可以当成模板来用

    #define mx 300
    #include<cstdio>
    #include<iostream>
    using namespace std; 
    struct gaojing{
         int len;
         int a[mx+10];
    };//定义高精度非负数类型
    gaojing zero,one;
    inline void set0(gaojing &s)
    {
        s.len=1;
        for (int i=1;i<=mx+5;i++)s.a[i]=0;
    }
    inline void inputn(gaojing &a)
    {
    	set0(a);
        char ch=getchar();
        while (ch<'0'||ch>'9')ch=getchar();  
        while (ch>='0'&&ch<='9')  
        {  
            a.a[a.len++]=ch-'0';
            ch=getchar();
        }
        a.len--;  
        int change[mx+15];
        for (int i=1;i<=a.len;i++)  
          change[i]=a.a[i];  
        for (int i=1;i<=a.len;i++)  
          a.a[i]=change[a.len-i+1];
        while (a.a[a.len]==0)a.len--;
    }  
    inline void put(gaojing a)
    {
        for (int i=a.len;i>=1;i--)printf("%d",a.a[i]);
        printf("
    ");
    }
    inline bool operator < (const gaojing &a,const gaojing &b)
    {
    	if (a.len<b.len)return 1;
    	if (a.len>b.len)return 0;
    	for (int i=a.len;i>=1;i--)
    	{
    		if (a.a[i]<b.a[i])return 1;
    		if (a.a[i]>b.a[i])return 0;
    	}
    	return 0;
    }
    inline bool operator == (const gaojing &a,const gaojing &b)
    {
    	if (a.len!=b.len)return 0;
    	for (int i=a.len;i>=1;i--)
    	{
    		if (a.a[i]!=b.a[i])return 0;
    	}
    	return 1;
    }
    inline gaojing max(const gaojing &a,const gaojing &b)
    {
        if (a<b)return b;
        else return a;
    }
    inline gaojing min(const gaojing &a,const gaojing &b)
    {
    	if (a<b)return a;
    	else return b;
    } 
    inline gaojing operator + (const gaojing &a,const gaojing &b)
    {
        gaojing c;set0(c);  
        int maxlen=max(a.len,b.len);      
        for (int i=1;i<=maxlen;i++)      
        {      
            c.a[i]=c.a[i]+a.a[i]+b.a[i];      
            if (c.a[i]>=10)      
            {      
                c.a[i+1]+=c.a[i]/10;    
                c.a[i]%=10;    
            }    
        }      
        c.len=maxlen+4;      
        while (!c.a[c.len]&&c.len>1) c.len--;    
        return c;
    }
    inline gaojing operator - (const gaojing &a,const gaojing &b)
    {
    	gaojing c;set0(c);
    	gaojing d;d=a;
        for (int i=1;i<=b.len;i++)  
          {  
            c.a[i]=d.a[i]-b.a[i];  
            if (c.a[i]<0)  
            {  
                c.a[i]+=10;  
                int now=i+1;  
                while (!d.a[now])  
                {  
                    d.a[now]=9;  
                    now++;  
                }  
                d.a[now]--;  
            }  
          }
        for (int i=b.len+1;i<=d.len;i++)c.a[i]=d.a[i];  
        c.len=d.len;  
        while (c.a[c.len]==0&&c.len>1)c.len--;
        return c;
    }  
    inline gaojing operator * (const gaojing &a,const gaojing &b)
    {
        gaojing c;set0(c);
        for(int i=1;i<=a.len;i++)    
          for (int j=1;j<=b.len;j++)    
            c.a[i+j-1]+=a.a[i]*b.a[j];    
        c.len=a.len+b.len+5;  
        for (int i=1;i<=c.len;i++)    
          {    
            c.a[i+1]+=c.a[i]/10;    
            c.a[i]%=10;    
          }    
        while (!c.a[c.len]&&c.len>1)c.len--;
        return c;
    }
    inline void div_by_2(gaojing &a)
    {
    	for (int i=a.len;i>=1;i--)
    	{
    		if (a.a[i]&1 && i!=1)a.a[i-1]+=10;
    		a.a[i]/=2;
    	}
    	while (!a.a[a.len]&&a.len>1)a.len--;
    }
    inline gaojing operator / (gaojing a,const gaojing &b)
    {
    	gaojing l,r,ans;
    	set0(l);l.len=1;
    	set0(r);r=a;
    	set0(ans);ans.len=1;
    	while (l<r||l==r)
    	{
    		gaojing mid=l+r;
    		div_by_2(mid);
    		if(mid*b==a)return mid;
    		if(mid*b<a){ans=mid;l=mid+one;}
    		if(a<mid*b)r=mid-one;
    	}
    	return ans;
    }
    inline void chushihua()
    {
    	set0(zero);	zero.len=1;
    	set0(one);one.len=1;one.a[1]=1;
    }
    inline gaojing gcd(const gaojing &a,const gaojing &b)
    {
    	if (b==zero)return a;
    	return gcd(b,a-a/b*b);
    }
    int main()
    {
    	gaojing a,b;
    	chushihua();
    	inputn(a);
    	inputn(b);
    	put(a/gcd(a,b)*b);
    }
    

      

    ——by zhber,转载请注明来源
  • 相关阅读:
    DateGridView 分页显示
    DataGridView 隔行显示不同的颜色
    DataGridview 绘制行序号
    DataGrridView 当前行显示不同颜色
    右键删除行
    【bzoj2763】[JLOI2011]飞行路线 分层图最短路
    【bzoj1143】[CTSC2008]祭祀river Floyd+网络流最小割
    【bzoj1029】[JSOI2007]建筑抢修 贪心+堆
    【bzoj1054】[HAOI2008]移动玩具 Bfs
    【bzoj1911】[Apio2010]特别行动队 斜率优化dp
  • 原文地址:https://www.cnblogs.com/zhber/p/4093520.html
Copyright © 2011-2022 走看看