【题目大意】

定义times(a, b)表示用辗转相除计算a和b的最大公约数所需步骤。

那么有:

1. times(a, b) = times(b, a)

2. times(a, 0) = 0

3. times(a, b) = times(b, a mod b) + 1

对于$1 \leq x \leq A, 1 \leq y \leq B$,求times(A, B)的最大值,以及有多少对数取到了最大值。

多组数据。

$T \leq 3 \times 10^5, 1 \leq A,B \leq 10^{18}$

【题解】

我们打一个1000以内,times(x, y) = 13的表

我们定义好数对为:$(x,y)$满足不存在$1 \leq x' \leq x, 1\leq y'\leq y$,使得times(x', y') > times(x, y)

那么明显答案肯定是好数,我们发现,答案中的很多数都是由$(x,y)$经过$(x, x+ky)$变换来的。

那么答案很多,但是$(x,y)$这样的数少,我们定义这样的数为极好数

严格定义为$x \leq fib_{x+2}, y \leq fib_{x+2}$且times(x, y) = k的好数。

我们可以发现并证明(显然),好数只要1步就能变成极好数

那么我们只要求出极好数,就能推出好数的数量了。

容易发现极好数很少,只要暴力求即可。

比如当times = 13的时候,极好数的个数只有13.。。

(就是把上面所有好数简化过后)

那么我们就能暴力求啦

发现times = x的极好数,是根据times = x-1的极好数(x, y)经过变换(y, x+ky)而来。那么我们只要根据极好数的定义求即可。

复杂度$O(Qlog^2(A))$

# include <vector>
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm> using namespace std; typedef long long ll;
typedef unsigned long long ull;
typedef long double ld; const int N = 1e5 + , M = 2e5 + , F = ;
const int mod = 1e9 + ; inline ll getll() {
ll x = ; char ch = getchar();
while(!isdigit(ch)) ch = getchar();
while(isdigit(ch)) x = x * + ch - '', ch = getchar();
return x;
} ll fib[F]; struct pa {
ll a, b;
pa() {}
pa(ll a, ll b) : a(a), b(b) {}
friend bool operator == (pa a, pa b) {
return a.a == b.a && a.b == b.b;
}
friend bool operator < (pa a, pa b) {
return a.a < b.a || (a.a == b.a && a.b < b.b);
}
friend bool operator > (pa a, pa b) {
return a.a > b.a || (a.a == b.a && a.b > b.b);
}
}; vector<pa> g[M]; int times = ;
inline int gcd(ll a, ll b) {
if(a < b) swap(a, b);
if(b == ) return a;
++times;
return gcd(b, a%b);
} inline int calc(ll a, ll b) {
times = ;
gcd(a, b);
return times;
} inline void gg(int x) {
pa t; g[x].clear();
for (int i=; i<g[x-].size(); ++i) {
t = g[x-][i];
ll y = t.b; swap(t.a, t.b);
for (t.b += y; t.b <= fib[x+]; t.b += y)
if(calc(t.a, t.b) == x) g[x].push_back(t);
}
sort(g[x].begin(), g[x].end());
g[x].erase(unique(g[x].begin(), g[x].end()), g[x].end());
} ll A, B, ans, tem;
inline void sol() {
A = getll(), B = getll();
if(A > B) swap(A, B);
ans = ; tem = ;
for (int i=; i<; ++i)
if(fib[i] <= A && fib[i+] <= B) ans = i;
else break;
printf("%d ", ans);
if(ans == ) {
printf("%d\n", A % mod * (B % mod) % mod);
return ;
} else {
for (int i=; i<g[ans-].size(); ++i) {
ll a = g[ans-][i].a, b = g[ans-][i].b;
if(b <= A) tem += (B-a)/b, tem %= mod;
if(b <= B) tem += (A-a)/b, tem %= mod;
}
}
printf("%lld\n", tem);
} int main() {
// freopen("gcd.in", "r", stdin);
// freopen("gcd.out", "w", stdout);
fib[] = , fib[] = ;
for (int i=; i<=; ++i) fib[i] = fib[i-] + fib[i-];
g[].push_back(pa(1ll, 2ll)), g[].push_back(pa(1ll, 3ll));
for (int i=; i<=; ++i) gg(i);
int T; cin >> T;
while(T--) sol();
return ;
}

upd: 加了个读入优化跑了rk2 

「6月雅礼集训 2017 Day8」gcd的更多相关文章

  1. 「6月雅礼集训 2017 Day8」route

    [题目大意] 给出平面上$n$个点,求一条连接$n$个点的不相交的路径,使得转换的方向符合所给长度为$n-2$的字符串. $n \leq 5000$ [题解] 考虑取凸包上一点,然后如果下一个是‘R' ...

  2. 「6月雅礼集训 2017 Day8」infection

    [题目大意] 有$n$个人,每个人有一个初始位置$x_i$和一个速度$v_i$,你需要选择若干个人来感染一个傻逼病毒. 当两个人相遇(可以是正面和背面),傻逼病毒会传染,求经过无限大时间后,传染完所有 ...

  3. 「6月雅礼集训 2017 Day10」quote

    [题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...

  4. 「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)

    原题传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2687 [题目大意] 给出若干区间,求一个区间的大于等于2的子集,使得 |区间并| 和 | ...

  5. 「6月雅礼集训 2017 Day11」delight

    [题目大意] 有$n$天,每天能吃饭.睡觉.什么事也不干 每天吃饭的愉悦值为$e_i$,睡觉的愉悦值为$s_i$,什么都不干愉悦值为0. 要求每连续$k$天都要有至少$E$天吃饭,$S$天睡觉. 求最 ...

  6. 「6月雅礼集训 2017 Day11」jump

    [题目大意] 有$n$个位置,每个位置有一个数$x_i$,代表从$i$经过1步可以到达的点在$[\max(1, i-x_i), \min(i+x_i, n)]$中. 定义$(i,j)$的距离表示从$i ...

  7. 「6月雅礼集训 2017 Day11」tree

    [题目大意] 给出一棵带权树,有两类点,一类黑点,一类白点. 求切断黑点和白点间路径的最小代价. $n \leq 10^5$ [题解] 直接最小割能过..但是树形dp明显更好写 设$f_{x,0/1/ ...

  8. 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)

    [题目大意] 给出一个$n$个数的序列$\{a_n\}$,其中有些地方的数为0,要求你把这个序列填成一个1到$n$的排列,使得: $(a_i, a_j) = 1$,当且仅当$(i, j) = 1$.多 ...

  9. 「6月雅礼集训 2017 Day7」电报

    [题目大意] 有n个岛屿,第i个岛屿有有向发射站到第$p_i$个岛屿,改变到任意其他岛屿需要花费$c_i$的代价,求使得所有岛屿直接或间接联通的最小代价. $1 \leq n \leq 10^5, 1 ...

随机推荐

  1. 福大软工1816:Alpha(9/10)

    Alpha 冲刺 (9/10) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.完善通过父子进程调用wxp ...

  2. 1001 Duplicate Pair

    1.题目戳这里 2.代码: #include<stdio.h> #include<string.h> int main() { int n; while(scanf(" ...

  3. TCP系列35—窗口管理&流控—9、紧急机制

    一.概述 我们在最开始介绍TCP头结构的时候,里面有个URG的标志位,还有一个Urgent Pointer的16bits字段.当URG标志位有效的时候,Urgent Poinert用来指示紧急数据的相 ...

  4. Unity3d学习日记(二)

      跟着教程做让背景可以滚动起来并添加了背景的粒子特效,加入了敌机.   ctrl攻击,↑↓←→移动,Game Over后按R重新开始游戏.   Space Shooter游戏地址:http://ya ...

  5. 敏捷冲刺Day2

    一. 每日会议 1. 照片 2. 昨日完成工作 网页设计与实现的完善 服务器的搭建前期--申请域名 激活域名 搭建服务器 分析接下来的任务与进度 总结前两天的工作 对产品的进一步展望 3. 今日完成工 ...

  6. Jmeter系列-自动生成html报告

    从JMeter 3.0开始已支持自动生成动态报告,我们可以更容易根据生成的报告来完成我们的性能测试报告. 如何生成html测试报告 如果未生成结果文件(.jtl),可运行如下命令生成报告: jmete ...

  7. SERVER 2008 R2 SP1下的内存虚拟盘(支持32位,64位的所有windows版本)

    一时冲动把笔记本的系统换成了2008 R2 SP1的,本来想着用笔记本开HYPER-V的,结果是失败了,我发现我的4750G开了HYPER-V后CPU一直居高不下,其中有个什么系统软件保护的服务就占用 ...

  8. sql 插入列放第一列

    如果是SQLSERVER 的话就这样:select * from dbo.syscolumns where id=OBJECT_ID(N'你的表名') 然后COLID这列就是列的顺序 修改这个字段就行 ...

  9. 【bzoj2502】清理雪道 有上下界最小流

    题目描述 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降的方向. 你的团队负责每周定时清理雪道.你们拥有一架直升飞 ...

  10. web服务器压测工具siege、ab

    web服务器压测工具也挺多,这里只介绍我用过的这两种--siege(for linux).ab(for windows). 一.siege 1.简介: Siege是一款开源的压力测试工具,设计用于评估 ...