• 「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 imes 10^5, 1 leq A,B leq 10^{18}$

    【题解】

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

    我们定义好数对为:$(x,y)$满足不存在$1 leq x' leq x, 1leq 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 + 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
    ", 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
    ", 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 

  • 相关阅读:
    SQL Server, Timeout expired.all pooled connections were in use and max pool size was reached
    javascript 事件调用顺序
    Best Practices for Speeding Up Your Web Site
    C语言程序设计 使用VC6绿色版
    破解SQL Prompt 3.9的几步操作
    Master page Path (MasterPage 路径)
    几个小型数据库的比较
    CSS+DIV 完美实现垂直居中的方法
    由Response.Redirect引发的"Thread was being aborted. "异常的处理方法
    Adsutil.vbs 在脚本攻击中的妙用
  • 原文地址:https://www.cnblogs.com/galaxies/p/20170624_c.html
Copyright © 2020-2023  润新知