洛谷 2152 [SDOI2009]SuperGCD
Description
Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个程序来教训他。
Input
共两行: 第一行:一个数A。 第二行:一个数B。
Output
一行,表示A和B的最大公约数。
Sample
12
54
6
Hints
对于20%的数据,0 < A , B ≤ 10 ^ 18。
对于100%的数据,0 < A , B ≤ 10 ^ 10000。
我的数学可能要完了,我看完数据范围以后想算一下如果用辗转相除的话能不能过
我发现我不会算,可是不会其他算gcd的方法了诶
看到题解,发现大家都用了gcd和疑似gcd的方法
我又尝试算了一下复杂度,这个时候我打开了计算器,可是太大了,会溢出......
然后恍然大悟ToT
Solution
可以写辗转相除,但是我不想写高精取模,但是有一个叫Stein的方法
[1]. 若 aa 为奇数,bb 为偶数,GCD(a, b) = GCD(a, b / 2)GCD(a,b)=GCD(a,b/2)
表示 bb 存在2这个因子而 aa 不存在,则将 bb 除以2,,不考虑因子2;
[2]. 若 aa 为偶数,bb 为奇数,GCD(a, b) = GCD(a / 2, b)GCD(a,b)=GCD(a/2,b)
表示 aa 存在2这个因子而 bb 不存在,则将 aa 除以2,不考虑因子2;
[3]. 若 aa 为偶数,bb 为偶数,GCD(a, b) = GCD(a / 2, b / 2)GCD(a,b)=GCD(a/2,b/2)
表示 a, ba,b 都存在2这个因子,则 GCD(a, b)GCD(a,b) 也存在因子2,则将当前答案乘以2,a, ba,b 都除以2;
[4]. 若 aa 为奇数,bb 为奇数,GCD(a, b) = GCD(a - b, b) (a > b)GCD(a,b)=GCD(a−b,b)(a>b)
因为位数太多,所以要压位,因为只有*2,/2,-的操作,所以可以多压一点
De了很久的bug
一开始写的是递归版的gcd,暴栈了,递归到某一个函数里时,就会RE
后来发现输入有问题,不能用getline,会读空格进来,cin是不读空格的
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<string>
using namespace std;
const int w=1000000000,wi=9;
struct big{
int a[2001];
int len;
big(){memset(a,0,sizeof(a));len=0;}
big(string x){ //初始化的时候赋值需要找big(string)
*this = x;
}
bool operator <(const big&v){
if(len!=v.len)
return len<v.len;
for(int i=len;i>=1;i--)
if(a[i]!=v.a[i])
return a[i]<v.a[i];
return 0;
}
big& operator =(string v){
len=0;int lv=v.length();
for(int i=lv-1;i>=0;i-=wi)
{
int val=0;
for(int j=max(i-wi+1,0);j<=i;j++)
val=val*10+v[j]-'0'; //v[j]写成了j
a[++len]=val;
}
return *this;
}
big& operator =(big&v){
len=max(len,v.len); //取max,因为要把本来有的但是赋值以后没有的位变成0
for(int i=1;i<=len;i++)
a[i]=v.a[i];
while(len&&!a[len]) --len;
return *this;
}
big& operator -(big&v){
big res;
res.len=len;
for(int i=1;i<=len;i++)
{
res.a[i]+=a[i]-v.a[i];
if(res.a[i]<0)
{
res.a[i]+=w;
res.a[i+1]--;
}
}
while(res.len&&!res.a[res.len]) --res.len; //res.len不为负
return res;
}
big& operator /(int v){
big res;
res.len=len;
for(int i=len;i>=1;i--)
{
res.a[i]=a[i]/v;
a[i-1]+=(a[i]-v*res.a[i])*w;
}
while(res.len&&!res.a[res.len]) --res.len;
return res;
}
big& operator *(int v){
big res;
res.len=len+1;
for(int i=1;i<=len;i++)
{
res.a[i]+=a[i]*2;
res.a[i+1]+=res.a[i]/w;
res.a[i]=res.a[i]%w;
}
while(res.len&&!res.a[res.len]) --res.len;
return res;
}
};
int read()
{
int ans=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
return ans*f;
}
big mid;int mi=0;
big gcd(big a,big b)
{
while(b.len)
{
if(a<b)
{
mid=a;a=b;b=mid;
}
if(!b.len)
return a;
if(a.a[1]&1&&b.a[1]&1)
{
mid=b;
b=a-b;
a=mid;
}
else if(a.a[1]&1)
{
b=b/2;
}
else if(b.a[1]&1)
{
a=a/2;
}
else
{
a=a/2;b=b/2;mi++;
}
}
for(int i=1;i<=mi;i++)
a=a*2;
return a;
}
int main()
{
// freopen("o.txt","r",stdin);
// freopen("oo.out","w",stdout);
string a,b;
cin>>a>>b; //不能用cin要读空格
big a1,b1;
a1=a;b1=b;
big ans=gcd(a1,b1);
for(int i=ans.len;i>=1;i--)
if(i==ans.len)
printf("%d",ans.a[i]);
else
printf("%09d",ans.a[i]);
return 0;
}
/*
111111111111111
111111111111110
*/
洛谷 2152 [SDOI2009]SuperGCD的更多相关文章
- 洛谷 P2152 [SDOI2009]SuperGCD (高精度)
这道题直接写了我两个多小时-- 主要是写高精度的时候还存在着一些小毛病,调了很久 在输入这一块卡了很久. 然后注意这里用while的形式写,不然会炸 最后即使我已经是用的万进制了,但是交上去还是有两个 ...
- 洛谷 P2152 [SDOI2009]SuperGCD
题意简述 求两个整数a,b的最大公约数0 < a , b ≤ 10 ^ 10000. 题解思路 如果 a % 2 == 0 && b % 2 == 0 gcd(a,b) = gc ...
- 洛谷P1972 [SDOI2009]HH的项链 题解
[SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不 ...
- BZOJ1880或洛谷2149 [SDOI2009]Elaxia的路线
BZOJ原题链接 洛谷原题链接 显然最长公共路径是最短路上的一条链. 我们可以把最短路经过的边看成有向边,那么组成的图就是一张\(DAG\),这样题目要求的即是两张\(DAG\)重合部分中的最长链. ...
- 洛谷P2148 [SDOI2009]E&D(博弈论)
洛谷题目传送门 先安利蒟蒻仍在施工的博弈论总结 首先根据题目,石子被两两分组了,于是根据SG定理,我们只要求出每一组的SG值再全部异或起来就好啦. 把每一对数看成一个ICG,首先,我们尝试构造游戏的状 ...
- BZOJ1227或洛谷2154 [SDOI2009]虔诚的墓主人
BZOJ原题链接 洛谷原题链接 又是扫描线,题解可看大佬的博客(太懒了不想打) #include<cstdio> #include<algorithm> using names ...
- BZOJ1228或洛谷2148 [SDOI2009]E&D
BZOJ原题链接 洛谷原题链接 完全不会呀.. 写了这题才知道\(SG\)函数原来也能打表找规律... 题解请看大佬的博客 #include<cstdio> using namespace ...
- BZOJ1226或洛谷2157 [SDOI2009]学校食堂
BZOJ原题链接 洛谷原题链接 注意到\(B[i]\)很小,考虑状压\(DP\). 设\(f[i][j][k]\)表示前\(i - 1\)个人已经拿到菜,第\(i\)个人及其后面\(7\)个人是否拿到 ...
- [洛谷P1972][SDOI2009]HH的项链
题目大意:给你一串数字,多次询问区间内数字的种类数 题解:莫队 卡点:洛谷数据加强,开了个$O(2)$ C++ Code: #include <cstdio> #include <a ...
随机推荐
- pycharm 测试执行成功,但却无法成功生成测试报告(使用HTMLTestRunner)的解决办法
pycharm 测试执行成功,在对应的测试路径下确未生成测试报告.反复确认代码也是没有问题的,在网上查找了原因:简单的unittest运行是不执行main方法的.是允许方式问题. 于是在mian方法里 ...
- C#截取字符串的方法小结(转)
1.单个字符分隔用split截取 string str = "GT123_1"; string[] strArray = str.Split('_'); //输出:sArray[0 ...
- JDBC vs Hibernate(转)
jdbc和Hibernate区别 刚开始学习JAVA时,认为Hibernate是一个很神圣的东西,好像是会了SSH,就能走遍全世界一样.记得曾经在枫叶面试的时候,我们几个同学出还说这个公司怎么这么的落 ...
- 重磅!阿里云Promtheus 正式免费公测
每日头条 重磅!容器集群监控利器 阿里云Promtheus 正式免费公测 Prometheus 作为容器生态下集群监控的首选方案,是一套开源的系统监控报警框架.2019 年7月3日,阿里云Promth ...
- golang变量-数据类型一
package main import "fmt" var t1 = 100 var t2 = 200 var t3 = 300 var ( u1 = 100 u2 = 200 u ...
- 值得研究的J2EE开源项目推荐
导读:笔者在学习J2EE的过程中发现了一些很有用,而且很值得学习的开源项目,在此推荐给大家. 关键词:J2EE 开源项目 J2SE JBoss SOA EJB 这篇文章写在我研究J2SE.J2EE ...
- oralce如何修改默认的XDB监听端口
Oracle9i默认的XML DB把HTTP的默认端口设为8080,这是一个太常用的端口了,很多别的WebServer都会使用这个端口, 如果我们安装了它,最好修改一下,避免冲突,如果不使用呢,就最好 ...
- sql —— check
CHECK 约束用于限制列中的值的范围. 原表: 现在要对性别这一列进行约束,只准值为男或者女. 步骤: 1. 2. 3. 4. 5. ctrl + s 保存一下, 现在不可以随意的修改性别了. 完成 ...
- hdu 3536【并查集】
hdu 3536 题意: 有N个珠子,第i个珠子初始放在第i个城市.有两种操作: T A B:把A珠子所在城市的所有珠子放到B城市. Q A:输出A珠子所在城市编号,该城市有多少个珠子,该珠子转移了 ...
- KiCad EDA 镜像目录说明
KiCad EDA 镜像目录说明 stable/ -- 稳定版安装包. testing/ -- 测试安装包. nightly/ -- 每日编译安装包. 5.1 版本的每日编译包,这个文件夹是重点,如果 ...