题意

求\(\gcd(a, b)\),其中\(a,b\leq10^{10000}\)

题解

使用\(\text{Stein}\)算法,其原理是不断筛除因子\(2\)然后使用更相减损法

如果不筛\(2\)因子的话复杂度是线性的,比如\(a=1,b=10^{10000}\)

再证明下更相减损术,即\(\gcd(a,b)=gcd(a-b,b)\):

假设\(d=\gcd(a,b)\),则\(a=pd,b=qd\)

根据定义可知\(\gcd(p,q)=1\)

因此\(px+qy=1\)存在解\(x,y\)

此时\(a-b=pd-q-d=(p-q)d,b=qd\)

\((p-q)x+q(x+y)=px+qy=1\)

得到\(\gcd(p-q,q)=1\),根据定义得到\(d=\gcd(a-b,b)\)

注意一下高精要压位,不然常数巨大

#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cstdio>
using namespace std; const int base = 1e9;
const int N = 1e4 + 10; struct Int {
int len, n[N / 9 + 10];
Int() {}
Int(char * s) {
int x = strlen(s);
len = x / 9 + (x % 9 ? 1 : 0);
int p = x - 1;
for(int i = 1; i <= len; i ++) {
n[i] = 0;
for(int j = min(p, 8); j >= 0; j --)
n[i] = n[i] * 10 + (s[p - j] & 15);
p -= 9;
}
}
bool zero() { return len == 1 && n[1] == 0; }
bool judge() { return !zero() && 0 == (n[1] & 1); }
bool operator < (const Int &b) const {
if(len != b.len) return len < b.len;
for(int i = len; i >= 1; i --)
if(n[i] != b.n[i]) return n[i] < b.n[i];
return 0;
}
bool operator -= (const Int &b) {
for(int i = 1; i <= len; i ++) {
if(i <= b.len) {
n[i] -= b.n[i];
if(n[i] < 0) n[i + 1] --, n[i] += base;
}
}
for(; !n[len] && len > 1; len --);
return zero();
}
void div2() {
for(int i = 1; i <= len; i ++) {
if(n[i] & 1) n[i - 1] += base >> 1;
n[i] >>= 1;
}
for(; !n[len] && len > 1; len --);
}
void operator <<= (const int &x) {
for(int t = 1; t <= x; t ++) {
n[len + 1] = 0;
for(int i = len; i >= 1; i --) {
n[i] <<= 1; n[i + 1] += n[i] / base; n[i] %= base;
}
if(n[len + 1]) len ++;
}
this -> print();
}
void print() {
for(int i = len; i >= 1; i --)
if(i == len) printf("%d", n[i]);
else printf("%09d", n[i]);
printf("\n");
}
} x, y; int main() {
static char A[N], B[N];
scanf("%s %s", A, B);
x = Int(A), y = Int(B);
if(x.zero()) return y.print(), 0;
if(y.zero()) return x.print(), 0;
int i = 0, j = 0;
for(; x.judge(); i ++) x.div2();
for(; y.judge(); j ++) y.div2();
while(1) {
if(!(x < y)) {
if(x -= y) return y <<= min(i, j), 0;
while(x.judge()) x.div2();
} else {
if(y -= x) return x <<= min(i, j), 0;
while(y.judge()) y.div2();
}
}
return 0;
}

「BZOJ 1876」「SDOI 2009」SuperGCD「数论」的更多相关文章

  1. 【BZOJ 1877】【SDOI 2009】晨跑

    拆点跑$MCMF最小费用最大流$ 复习一下$MCMF$模板啦啦啦--- 一些坑:更新$dist$后要接着更新$pre$,不要判断是否在队列中再更新,,,听不懂吧,听不懂就对了,因为只有我才会在这种错误 ...

  2. 【BZOJ 1875】【SDOI 2009】HH去散步

    水啊水,最后ans别忘了%哦! #include<cstdio> #include<cstring> #include<algorithm> using names ...

  3. 「SDOI 2009」Elaxia的路线

    发现自己这几天智商完全不在线-- 这道题的数据十分的水,怎样都可以艹过去-- 开始想了一个完全错误的算法,枚举一对点,判断这一对点是否同时在两条最短路上,是就用两点之间的路径更新答案.显然这样是错的: ...

  4. 「BZOJ 4228」Tibbar的后花园

    「BZOJ 4228」Tibbar的后花园 Please contact lydsy2012@163.com! 警告 解题思路 可以证明最终的图中所有点的度数都 \(< 3\) ,且不存在环长是 ...

  5. 「BZOJ 3645」小朋友与二叉树

    「BZOJ 3645」小朋友与二叉树 解题思路 令 \(G(x)\) 为关于可选大小集合的生成函数,即 \[ G(x)=\sum[i\in c ] x^i \] 令 \(F(x)\) 第 \(n\) ...

  6. 「BZOJ 4502」串

    「BZOJ 4502」串 题目描述 兔子们在玩字符串的游戏.首先,它们拿出了一个字符串集合 \(S\),然后它们定义一个字符串为"好"的,当且仅当它可以被分成非空的两段,其中每一段 ...

  7. 「BZOJ 4289」 PA2012 Tax

    「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...

  8. 「BZOJ 2534」 L - gap字符串

    「BZOJ 2534」 L - gap字符串 题目描述 有一种形如 \(uv u\) 形式的字符串,其中 \(u\) 是非空字符串,且 \(v\) 的长度正好为 \(L\), 那么称这个字符串为 \( ...

  9. 「BZOJ 2956」模积和

    「BZOJ 2956」模积和 令 \(l=\min(n,m)\).这个 \(i\neq j\) 非常不优雅,所以我们考虑分开计算,即: \[\begin{aligned} &\sum_{i=1 ...

随机推荐

  1. Zabbix 客户端自定义端口监控

    http://www.linuxidc.com/Linux/2013-05/83780.htm 

  2. STM32用有源蜂鸣器实现闹钟的声响

    有源蜂鸣器的声音是固定的,工作电压恒定,改变通断电的时间获得不同时长的音响,譬如连续音.快速短音.慢速长音(类似莫尔斯电报)来区分不同的报警信息. 简单的说,有源蜂鸣器只能发出一种声音,因为它的频率是 ...

  3. java 调用webservice (asmx) 客户端开发示例

    这是本人第一次写博客,其实就是自己做个笔记,写的很粗糙,也希望能给跟我遇到同样问题的你一点帮助. 因为最近有个项目要调用webservice接口,之前接触的都是Java开发服务端和客户端的接口,开发前 ...

  4. ansible命令详解

    查看ansible版本 import ansible print(ansible.__version__) 命令参数 -m:要执行的模块,默认为command -a:模块的参数 -u:ssh连接的用户 ...

  5. ORA-01940:无法删除当前已链接的用户

    (1)查看用户的连接状况 select user name, sid, serial# from v$session; (2)找到要删除用户的sid,和serial,并删除 例如要删除用户nc633t ...

  6. Postman之token动态获取

    目前项目涉及PC及APP端接口共用问题,后台接口给登陆后的用户设置了一个token,接口调用时请求头的参数值必须要动态生成,为了解决这个问题,查看Postman API文档,配置了可以方便后端开发者的 ...

  7. 安装gdb insight(6.8.1)

    如果之前安装过6.8或其它版本,请先删除以下目录 rm -rf /usr/local/insight rm -rf /usr/share/tcltk 如果之前设置过环境变量,也请删除 unset TC ...

  8. 优化tomcat配置(从内存、并发、缓存3个方面)优化

    Tomcat有很多方面,我从内存.并发.缓存三个方面介绍优化方法. 一.Tomcat内存优化 Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catal ...

  9. c++ 适配器模式(adapter)

    当两个系统的接口不一样时,我们就要重新封装一下接口,以便于当前系统的调用.这种模式叫做适配器模式.适配器模式分为两种: 1.对象组合适配器(Object Adapter) 2.类适配器(Class A ...

  10. c语言打印空白星号矩形

    用户输入一个数字N,输出一个N*N的空心矩形,N最小为3 效果如下: 思路是这样的,首先拿到这道题是没有思路的,但我们可以举几个例子,当N等于3的情况,当N=5的情况,发现第一行和最后一行是相同的,而 ...