【题目链接】

点击打开链接

【算法】

1.关于求最大公约数的算法

若使用辗转相除法,那么显然会超时

不妨这样思考 :

要求gcd(a,b),

若a为偶数,b为偶数,则gcd(a,b) = 2 * gcd(a/2,b/2)

若a为偶数,b为奇数,则gcd(a,b) = gcd(a/2,b)

若a为奇数,b为偶数,则gcd(a,b) = gcd(a,b/2)

若a为奇数,b为奇数,则gcd(a,b) = gcd(b,a-b)

这个算法的时间复杂度是log级别的

2.高精度计算

          由于a,b<=10^100,所以要用高精度

如果每一位存一个数会超时,所以我们每一位可以多位,例如9位,这样既省时间又省空间

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN 10000
#define MAXL 1250
const int BASE = 1e9; struct INT {
int len;
int num[MAXL+];
} A,B,ans;
int i,n; inline bool odd(INT x) {
int sta=;
while (!x.num[sta]) sta++;
return x.num[sta+x.len-] % ;
} inline bool zero(INT x) {
int i;
for (i = ; i <= MAXL; i++) {
if (x.num[i] != )
return false;
}
return true;
} inline void read(INT &x) {
int i,l,s;
char ch[MAXN];
scanf("%s",ch);
x.len = ;
l = strlen(ch);
for (i = ; i < l % ; i++) x.num[] = (x.num[] << ) + (x.num[] << ) + ch[i] - '';
if (l % != ) x.len = ;
s = ;
for (i = l % ; i < l; i++) {
if (s == ) { x.len++; s = ; }
x.num[x.len] = (x.num[x.len] << ) + (x.num[x.len] << ) + ch[i] - '';
s++;
}
x.len++;
} inline void print(INT x) {
int i,sta=;
while (!x.num[sta]) sta++;
printf("%d",x.num[sta]);
for (i = sta + ; i < sta + x.len; i++) printf("%09d",x.num[i]);
puts("");
} INT operator -= (INT &a,INT b) {
int i,sta1=,sta2=;
static INT res;
res.len = ;
memset(res.num,,sizeof(res.num));
while (!a.num[sta1]) sta1++;
while (!b.num[sta2]) sta2++;
reverse(a.num,a.num+sta1+a.len);
reverse(b.num,b.num+sta2+b.len);
for (i = ; i < max(a.len,b.len); i++) {
if (a.num[i] < b.num[i]) {
a.num[i] += BASE;
a.num[i+]--;
}
res.num[res.len++] = a.num[i] - b.num[i];
}
while (res.len > && res.num[res.len-] == ) res.len--;
reverse(res.num,res.num+res.len);
a = res;
} bool operator < (INT a,INT b) {
int i,sta1=,sta2=;
if (a.len < b.len) return true;
if (b.len < a.len) return false;
while (!a.num[sta1]) sta1++;
while (!b.num[sta2]) sta2++;
for (i = ; i < a.len; i++) {
if (a.num[sta1+i] < b.num[sta2+i]) return true;
if (b.num[sta2+i] < a.num[sta1+i]) return false;
}
return false;
} inline void multipy2(INT &x) {
int i,sta=;
while (!x.num[sta]) sta++;
reverse(x.num+sta,x.num+sta+x.len);
for (i = sta; i < sta + x.len; i++) x.num[i] = x.num[i] << ;
for (i = sta; i < sta + x.len; i++) {
if (x.num[i] >= BASE) {
x.num[i+]++;
x.num[i] %= BASE;
}
}
if (x.num[sta+x.len]) x.len++;
reverse(x.num+sta,x.num+sta+x.len);
} inline void divide2(INT &x) {
int i,n=,sta=;
static INT res;
while (!x.num[sta]) sta++;
for (i = sta; i < sta + x.len; i++) {
if (x.num[i] & ) x.num[i+] += BASE;
x.num[i] >>= ;
}
if (!x.num[sta]) x.len--;
}
int main() { read(A); read(B);
if (A < B) swap(A,B);
while (!zero(B)) {
if (odd(A) && odd(B)) A -= B;
else if (!odd(A) && odd(B)) divide2(A);
else if (odd(A) && !odd(B)) divide2(B);
else {
divide2(A);
divide2(B);
n++;
}
if (A < B) swap(A,B);
}
while (n--) multipy2(A);
print(A); return ; }

【SDOI2009】SuperGCD的更多相关文章

  1. 【BZOJ】【1876】【SDOI2009】SuperGCD

    高精度+GCD 唔……高精gcd其实可以这么算: \[ GCD(a,b)= \begin{cases} a & b=0 \\ 2*GCD(\frac{a}{2},\frac{b}{2}) &a ...

  2. 【SDOI2009】解题汇总

    又开了波专题,感觉就和炉石开冒险一样...(说的好像我有金币开冒险似的) /---------------------------------------------/ BZOJ-1226 [SDOI ...

  3. 【SDOI2009】Bill的挑战

    Description Sheng bill不仅有惊人的心算能力,还可以轻松地完成各种统计.在昨天的比赛中,你凭借优秀的程序与他打成了平局,这导致Sheng bill极度的不满.于是他再次挑战你.这次 ...

  4. 【BZOJ】【1878】【SDOI2009】HH的项链

    树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边 ...

  5. 【BZOJ】【1877】【SDOI2009】晨跑

    网络流/费用流 费用流入门题……根本就是模板题好吗! 拆点搞定度数限制,也就是每个点最多经过一次……源点汇点除外. /***************************************** ...

  6. 【bzoj1875】【SDOI2009】【HH去散步】

    1875: [SDOI2009]HH去散步 Time Limit: 20 Sec Memory Limit: 64 MB Submit: 932 Solved: 424 [Submit][Status ...

  7. BZOJ 1227 【SDOI2009】 虔诚的墓主人

    Description 小W 是一片新造公墓的管理人.公墓可以看成一块 \(N×M\) 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意 ...

  8. 【SDOI2009】HH的项链

    洛谷题目链接 题意: 给定一个长5w静态的序列,询问20w次,每次询问查找一个区间内的元素种类数 染色问题神烦啊,最近刚会做,感觉都可以用统一的方法 首先要算出与一个元素相同的最邻近的上一个元素的位置 ...

  9. 【SDOI2009】HH去散步(矩阵快速幂)

    题面 题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是 ...

随机推荐

  1. Ryuji doesn't want to study (树状数组)

    [传送门]:https://nanti.jisuanke.com/t/31460 [题意]给定一个数组a[N],有两种操作, 操作1,给定 l , r,  查询a[l]×L+a[l+1]×(L−1)+ ...

  2. let与const命令

    (需要注意的地方) 1.ES6 新增了let命令,用来声明变量.它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效. 2.for循环还有一个特别之处,就是设置循环变量的那部分是一 ...

  3. luogu P2085 最小函数值

    题目描述 有n个函数,分别为F1,F2,...,Fn.定义Fi(x)=Ai*x^2+Bi*x+Ci (x∈N*).给定这些Ai.Bi和Ci,请求出所有函数的所有函数值中最小的m个(如有重复的要输出多个 ...

  4. springboot启动报异常,Failed to load property source from location 'classpath:/application.yml'

    学习springboot,在启动时抛出下图异常 往下看异常信息,找到异常的具体位置 找到application.yml文件的对应位置,发现params配置前面多了空格 去掉空格重新启动,可以了 写代码 ...

  5. [Javascript] Use a custom sort function on an Array in Javascript

    Sorting in Javascript with sort uses lexical sorting by default, which means it will sort in alphabe ...

  6. scss - 语法

    1.在一个样式导入另一个样式(@import "example.css") 2.scss单行注释不会显示出来 3.强大的变量(定义后,全局可使用) 4.全局默认变量(加!defau ...

  7. C#获取电脑的相关信息

    /* 创建者:菜刀居士的博客  * 创建日期: 2014年08月31号  * 功能:获取电脑的相关信息  *  */ namespace Net.String.ConsoleApplication { ...

  8. 算法和流程控制 --《高性能JavaScript》

    总结: 1.for, while, do-while循环性能相当,并没有一种循环类型明显快于或满于其他类型. 2.避免使用for-in循环,除非要遍历一个属性数量未知的对象. 3.改善循环性能的最佳形 ...

  9. Enum to String 一般用法

    目录 一.Enum Review 二.使用name()方法转换为String 三.使用toString()方法转换为String 四.使用成员属性转换为String 一.Enum Review ​ J ...

  10. Entity Framework 6 Code First 实践系列(1):实体类配置-根据依赖配置关系和关联

    EF实体类的配置可以使用数据注释或Fluent API两种方式配置,Fluent API配置的关键在于搞清实体类的依赖关系,按此方法配置,快速高效合理.为了方便理解,我们使用简化的实体A和B以及A.B ...