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("\n");
}
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);
}

  

时间: 2024-12-08 12:16:21

2014.11.12模拟赛【最小公倍数】| vijos1047最小公倍数的相关文章

2014.11.12模拟赛【最大公因数】

最大公因数(gcd.c/.cpp/.pas) 题目描述 给定正整数n,求. 样例输入 6 样例输出 15 数据范围 对于40%的数据:1<=n<=1000000 对于100%的数据:1<=n<=3*10^12 提示:保证答案不超过10^18 原创题! ……好吧其实最后发现bzoj2705[longge的问题]跟这个一毛一样,但是这个数据更强 不过我真是独立yy出来的 首先,考虑gcd(i,n)==k的i有几个 显然这是等价于gcd(j,n/k)==1的j有几个,其中1<=j&

2014.11.12模拟赛【美妙的数字】| vijos1904学姐的幸运数字

美妙的数字(number.c/.cpp/.pas) 题目描述 黄巨大认为非负整数是美妙的,并且它的数值越小就越美妙.当然0是最美妙的啦. 现在他得到一串非负整数,对于每个数都可以选择先对它做二进制非运算(模二意义下0.1互换,注意前导0也要交换),然后在任意相邻的两个数之间插入二进制与.二进制或,或者二进制异或.现在他想知道这样计算完产生的最美妙的数字是多少. 一共T组数据.对于每组数据,第一行一个n,表示这组数据中一串数有多少个.下面n个非负整数,表示这串数. 样例输入 2 2 3 6 3 1

11.12 模拟赛T2 冒泡排序图

[问题描述] 有一段使用冒泡排序产生一张图的伪代码如下:function bubbleSortGraph(n, a[]): graph = emptyGraph() repeat swapped = false for i = 1 to n - 1:  if a[i] > a[i + 1]: graph.addEdge(a[i], a[i + 1]) swap(a[i], a[i + 1]) swapped = true until not swapped return graph函数的输入为长

11.12 模拟赛T1 加密

[问题描述] 有一种不讲道理的加密方法是: 在字符串的任意位置随机插入字符. 相应的, 不讲道理的解密方法就是从字符串中恰好删去随机插入的那些字符. 给定原文?和加密后的字符串?,求?有多少子串可以通过解密得到原文?. [输入格式] 输入第一行包含一个字符串?,第二行包含一个字符串?. [输出格式] 输出一行,包含一个整数,代表可以通过解密得到原文的?的子串的数量. [样例输入] abcabcabccba [样例输出] 9 [样例解释] 用[l,r]表示子串开头结尾的下标(从 0 开始编号) ,

2017.6.11 校内模拟赛

题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛 T1 自己在纸上模拟一下后就会发现 可以用栈来搞一搞事情 受了上次zsq 讲的双栈排序的启发.. 具体就是将原盘子大小copy一下排个序 用两个指针维护两个数组(原数据 和 排序后的数据), 即分为1数据和2数组 将小于1指针指向的数据的2数组中的数据全部压入栈中 后进行消除, 将栈栈顶元素与当前1数组中的1指针指向的元素进行比较 相同则消除 后重复过程 直至指针超过N 后判断一下是否两个指针都超过了N... #incl

11.27 模拟赛

并没有人做的模拟赛... 出题人hx,,, T1:就是上一道矩阵乘法 数学题 T2: 一个数列中 一个区间满足,存在一个k(L <= k <= R),并且对于任意的i (L <= i <= R),ai都能被ak整除 这样的一个特殊区间 [L, R]价值为R - L 想知道序列中所有特殊区间的最大价值是多少,而有多少个这样的区间呢 这些区间又分别是哪些呢 输出每个区间的L 思路: 用两个ST表分别求一段区间的gcd和最小值 然后可以二分答案 check的时候枚举左端点,判断在这段区间

2017 9 11 noip模拟赛T2

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=205; int map[N][N]; int d[N],tag[N],book[N],f[N]; int n,m; void work(int x) { memset(d,63,sizeof(d)); memset(book,0,sizeof(book)); memset(f,0,sizeof(

11.4 模拟赛

终于AK了,虽然第三题主要是搞月想出来的 T1: n个1*1的小方块,把这些小方块拼成一个图形,使这个图形周长最小 思路: 枚举拼成长方形的长为i,宽为n/i 可得面积 (i+n/i+(bool)(n%i))*2 1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6 #include<cstr

11.12模拟考T1(可持续优化)PS:神奇的东西

1.数列操作   (array.pas/c/cpp) [问题描述] 现在有一个数列,最初包含0个数.现在要对数列操作n次,操作有3类. 1) a k,在数列的最后插入一个整数k 2) s 将最近插入的数删除. 3) t k 将数列恢复第k次操作前的状态 下面是一个例子,有12个操作 1 a 5 -> [5] => 5 加入数5 2 a 3 -> [5,3] => 3 加入数3 3 a 7 -> [5,3,7] => 7 加入数7 4 s -> [5,3] =>