「6月雅礼集训 2017 Day8」gcd
2017-06-24 19:41
357 查看
【题目大意】
定义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的表
View Code
upd: 加了个读入优化跑了rk2
定义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的表
# 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 + 10, M = 2e5 + 10, F = 105; const int mod = 1e9 + 7; inline ll getll() { ll x = 0; char ch = getchar(); while(!isdigit(ch)) ch = getchar(); while(isdigit(ch)) x = x * 10 + ch - '0', 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 = 0; inline int gcd(ll a, ll b) { if(a < b) swap(a, b); if(b == 0) return a; ++times; return gcd(b, a%b); } inline int calc(ll a, ll b) { times = 0; gcd(a, b); return times; } inline void gg(int x) { pa t; g[x].clear(); for (int i=0; i<g[x-1].size(); ++i) { t = g[x-1][i]; ll y = t.b; swap(t.a, t.b); for (t.b += y; t.b <= fib[x+2]; 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 = 1; tem = 0; for (int i=2; i<90; ++i) if(fib[i] <= A && fib[i+1] <= B) ans = i; else break; printf("%d ", ans); if(ans == 1) { printf("%d\n", A % mod * (B % mod) % mod); return ; } else { for (int i=0; i<g[ans-1].size(); ++i) { ll a = g[ans-1][i].a, b = g[ans-1][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[0] = 1, fib[1] = 1; for (int i=2; i<=90; ++i) fib[i] = fib[i-1] + fib[i-2]; g[1].push_back(pa(1ll, 2ll)), g[1].push_back(pa(1ll, 3ll)); for (int i=2; i<=88; ++i) gg(i); int T; cin >> T; while(T--) sol(); return 0; }
View Code
upd: 加了个读入优化跑了rk2
相关文章推荐
- 「6月雅礼集训 2017 Day8」route
- 「6月雅礼集训 2017 Day8」infection
- loj6045 「雅礼集训 2017 Day8」价
- 「6月雅礼集训 2017 Day4」寻找天哥
- 「6月雅礼集训 2017 Day7」电报
- 「6月雅礼集训 2017 Day10」quote
- 「6月雅礼集训 2017 Day5」仰望星空
- LOJ6045 「雅礼集训 2017 Day8」价
- 「6月雅礼集训 2017 Day11」delight
- 「6月雅礼集训 2017 Day2」A
- 「6月雅礼集训 2017 Day5」学外语
- 「6月雅礼集训 2017 Day1」看无可看
- 「6月雅礼集训 2017 Day4」暴力大神hxx
- 【LYOI 212】「雅礼集训 2017 Day8」价(二分匹配+最大权闭合子图)
- LOJ_6045_「雅礼集训 2017 Day8」价 _最小割
- LOJ6044 「雅礼集训 2017 Day8」共
- 「6月雅礼集训 2017 Day2」B
- 「6月雅礼集训 2017 Day10」perm(CodeForces 698F)
- 「6月雅礼集训 2017 Day7」回转寿司
- 「6月雅礼集训 2017 Day1」说无可说