「6月雅礼集训 2017 Day8」gcd
【题目大意】
定义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的更多相关文章
- 「6月雅礼集训 2017 Day8」route
[题目大意] 给出平面上$n$个点,求一条连接$n$个点的不相交的路径,使得转换的方向符合所给长度为$n-2$的字符串. $n \leq 5000$ [题解] 考虑取凸包上一点,然后如果下一个是‘R' ...
- 「6月雅礼集训 2017 Day8」infection
[题目大意] 有$n$个人,每个人有一个初始位置$x_i$和一个速度$v_i$,你需要选择若干个人来感染一个傻逼病毒. 当两个人相遇(可以是正面和背面),傻逼病毒会传染,求经过无限大时间后,传染完所有 ...
- 「6月雅礼集训 2017 Day10」quote
[题目大意] 一个合法的引号序列是空串:如果引号序列合法,那么在两边加上同一个引号也合法:或是把两个合法的引号序列拼起来也是合法的. 求长度为$n$,字符集大小为$k$的合法引号序列的个数.多组数据. ...
- 「6月雅礼集训 2017 Day4」qyh(bzoj2687 交与并)
原题传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2687 [题目大意] 给出若干区间,求一个区间的大于等于2的子集,使得 |区间并| 和 | ...
- 「6月雅礼集训 2017 Day11」delight
[题目大意] 有$n$天,每天能吃饭.睡觉.什么事也不干 每天吃饭的愉悦值为$e_i$,睡觉的愉悦值为$s_i$,什么都不干愉悦值为0. 要求每连续$k$天都要有至少$E$天吃饭,$S$天睡觉. 求最 ...
- 「6月雅礼集训 2017 Day11」jump
[题目大意] 有$n$个位置,每个位置有一个数$x_i$,代表从$i$经过1步可以到达的点在$[\max(1, i-x_i), \min(i+x_i, n)]$中. 定义$(i,j)$的距离表示从$i ...
- 「6月雅礼集训 2017 Day11」tree
[题目大意] 给出一棵带权树,有两类点,一类黑点,一类白点. 求切断黑点和白点间路径的最小代价. $n \leq 10^5$ [题解] 直接最小割能过..但是树形dp明显更好写 设$f_{x,0/1/ ...
- 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)
[题目大意] 给出一个$n$个数的序列$\{a_n\}$,其中有些地方的数为0,要求你把这个序列填成一个1到$n$的排列,使得: $(a_i, a_j) = 1$,当且仅当$(i, j) = 1$.多 ...
- 「6月雅礼集训 2017 Day7」电报
[题目大意] 有n个岛屿,第i个岛屿有有向发射站到第$p_i$个岛屿,改变到任意其他岛屿需要花费$c_i$的代价,求使得所有岛屿直接或间接联通的最小代价. $1 \leq n \leq 10^5, 1 ...
随机推荐
- Android 网络编程 API笔记 - java.net 包相关 接口 api
Android 网络编程相关的包 : 9 包, 20 接口, 103 类, 6 枚举, 14异常; -- Java包 : java.net 包 (6接口, 34类, 2枚举, 12异常); -- An ...
- Java容器之Collections
Collections 类来源于 java.util.Collections,从 java.lang.object继承. 此类完全由在 collection 上进行操作或返回 collection 的 ...
- css深入理解之 border
一 border-width不支持百分比值 1 不符合客观逻辑 2 w3成都一种约定吧 3 边框本身就像是一个包裹内容的界限 类似的还有outline,box-shadow text-shadow均不 ...
- Redis的概述和简单使用(转载)
文章来源:http://jingyan.baidu.com/article/db55b60996d0124ba30a2f92.html Redis是一个基于key-value的高速缓存系统,类似于me ...
- WPF绑定到父元素的属性的方法
应用:绑定到父元素的属性上的方法,看图.
- java 当读取的结果为-1时候说明已经读取结束了
当读取的结果为-1时候说明已经读取结束了
- bzoj2437-兔兔与蛋蛋
题目 分析 第一次做这种题,其实很简单. 只能经过一次的博弈可以考虑转化为二分图博弈. 棋盘上有黑白色的棋子,可以把这个游戏看作空格在棋子间移动,于是就想到,把棋盘黑白染色,以空格为黑,那么空格的移动 ...
- 2017中国大学生程序设计竞赛-哈尔滨站 A - Palindrome
Palindrome Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Tota ...
- Android APP性能优化(最新总结)
导语 安卓大军浩浩荡荡,发展已近十个年头,技术优化日异月新,如今Android 8.0 Oreo 都发布了,Android系统性能已经非常流畅了.但是,到了各大厂商手里,改源码自定系统,使得And ...
- 三个月死磕Python是种什么样的体验?
3个月的死磕Python后,参加「 楼+ Python实战 · 第4期 」的学员们感想如何?下面带来他们的真实评价. 作为实验楼的网红课程——「 楼+ Python实战 」已经走过了第四期,经过了三个 ...