【SDOI2009】SuperGCD
【题目链接】
【算法】
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的更多相关文章
- 【BZOJ】【1876】【SDOI2009】SuperGCD
高精度+GCD 唔……高精gcd其实可以这么算: \[ GCD(a,b)= \begin{cases} a & b=0 \\ 2*GCD(\frac{a}{2},\frac{b}{2}) &a ...
- 【SDOI2009】解题汇总
又开了波专题,感觉就和炉石开冒险一样...(说的好像我有金币开冒险似的) /---------------------------------------------/ BZOJ-1226 [SDOI ...
- 【SDOI2009】Bill的挑战
Description Sheng bill不仅有惊人的心算能力,还可以轻松地完成各种统计.在昨天的比赛中,你凭借优秀的程序与他打成了平局,这导致Sheng bill极度的不满.于是他再次挑战你.这次 ...
- 【BZOJ】【1878】【SDOI2009】HH的项链
树状数组/前缀和 Orz lct1999 好神的做法... 先看下暴力的做法:对于区间[l,r],我们依次扫过去,如果这个数是第一次出现,那么我们种类数+1. 我们发现:区间中相同的几个数,只有最左边 ...
- 【BZOJ】【1877】【SDOI2009】晨跑
网络流/费用流 费用流入门题……根本就是模板题好吗! 拆点搞定度数限制,也就是每个点最多经过一次……源点汇点除外. /***************************************** ...
- 【bzoj1875】【SDOI2009】【HH去散步】
1875: [SDOI2009]HH去散步 Time Limit: 20 Sec Memory Limit: 64 MB Submit: 932 Solved: 424 [Submit][Status ...
- BZOJ 1227 【SDOI2009】 虔诚的墓主人
Description 小W 是一片新造公墓的管理人.公墓可以看成一块 \(N×M\) 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意 ...
- 【SDOI2009】HH的项链
洛谷题目链接 题意: 给定一个长5w静态的序列,询问20w次,每次询问查找一个区间内的元素种类数 染色问题神烦啊,最近刚会做,感觉都可以用统一的方法 首先要算出与一个元素相同的最邻近的上一个元素的位置 ...
- 【SDOI2009】HH去散步(矩阵快速幂)
题面 题目描述 HH有个一成不变的习惯,喜欢饭后百步走.所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离. 但是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回. 又因为HH是 ...
随机推荐
- Codeforces 552E Vanya and Brackets(枚举 + 表达式计算)
题目链接 Vanya and Brackets 题目大意是给出一个只由1-9的数.乘号和加号组成的表达式,若要在这个表达式中加上一对括号,求加上括号的表达式的最大值. 我们发现,左括号的位置肯定是最左 ...
- linux crontab 定时器
crontab -e 编辑定时器 crontab -l 显示当前定时器 crontab -r 删除当前定时器 格式 * * * * * command 第一列表示分钟1-59 第二列表示小时1-23 ...
- 如何快速的知道Maven插件的命令行输入参数
用命令行使用Maven的插件时,-D表示属性的输入,-P表示构建配置文件的输入. 比如要使用package生命周期阶段对Application项目进行打包jar时,查找方式如下: 1.由于packag ...
- linux 系统命令----修改主机名
1. hostname ***** 2.修改/etc/sysconfig/network 3./etc/hosts 最后第三步没有必要!
- redis集群设置密码详解
原文:http://lookingdream.blog.51cto.com/5177800/1827851 注意事项: 1.如果是使用redis-trib.rb工具构建集群,集群构建完成前不要配置密码 ...
- 【sourcetree】sourcetree连接远程仓库需要登陆但是一直登陆不上的问题 解决方法
授权类型选用 基础 .只需要登陆你在bitbucket的用户名和密码 如下 .即可成功连接远程仓库
- [WASM + Rust] Debug a WebAssembly Module Written in Rust using console.log
Having some kind of debugging tool in our belt is extremely useful before writing a lot of code. In ...
- 出现异常时直接把e输出比输出e.getMessage()好得多
之前研究态度不好,出异常时处理草草了事,今天出现问题才觉得该认真对待每个分支.
- HDU 1284 钱币兑换问题 (完全背包)
钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- C++类使用static小例子(新手学习C++)
//为什么类的成员中不能包括动态分配的数据,若包含静态数据怎么使用?#include <iostream>using namespace std;class point{ priva ...