zoukankan      html  css  js  c++  java
  • LightOJ 1052

    Zibon just started his courses in Computer science. After having some lectures on programming courses he fell in love with strings. He started to play with strings and experiments on them. One day he started a string of arbitrary (of course positive) length consisting of only {a, b}. He considered it as 1st string and generated subsequent strings from it by replacing all the b's with ab and all the a's with b. For example, if he ith string is abab, (i+1)th string will be b(ab)b(ab) = babbab. He found that the Nth string has length X and Mth string has length Y. He wondered what will be length of the Kth string. Can you help him?

    Input

    Input starts with an integer T (≤ 200), denoting the number of test cases.
    Each case begins with five integers N, X, M, Y, K. (0 < N, M, X, Y, K < 109 and N ≠ M).

    Output

    For each case print one line containing the case number and L which is the desired length (mod 1000000007) or the string "Impossible" if it's not possible.

    Sample Input

    2
    3 16 5 42 6
    5 1 6 10 9
    

    Output for Sample Input

    Case 1: 68
    Case 2: Impossible
    

    题目大意就是说有一个初始字符串仅包含ab两个字符。经过N次变换字符串长度变为X,经过M次变换字符串长度变为Y,现在求经过K次变换后的字符串长度。(每次变换,将字符串中的a变为b,将字符串中b变为ab)。

    假设初始字符串中字符a,b的数量分别为x和y。

    初始状态字符```a```,```b```的数量为x和y
    经过1次变换后为 x + 2 * y
    经过2次变换后为 2 * x + 3 * y
    经过3次变换后为 3 * x + 5 * y
    经过4次变换后为 5 * x + 8 * y
    

    发现规律了吗?
    经过几次变换后,发现变换后的系数与斐波那契数列有关。
    设斐波那契数列是从1开始

    1 1 2 3 5 8 13 21 ...
    

    经过N次变换后,也就是第N+1个字符串。

    g(N+1) = f(N) * x + f(N + 1) * y;
    

    然后有这样的两个式子即可求得x和y,然后在求得第k个字符串长度。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef long long  ll;
    typedef vector<ll> vec;
    typedef vector<vec> mat;
    const ll mod = 1000000007;
    bool flag;
    
    mat mul(mat &a, mat &b)
    {
        mat c(a.size(), vec(b[0].size()));
        for(int i=0; i<a.size(); ++ i)
        {
            for(int k=0; k<b.size(); ++ k)
            {
                for(int j=0; j<b[0].size(); ++ j)
                {
                    c[i][j] = c[i][j] + a[i][k]*b[k][j];
                    if(c[i][j] >= mod)
                    {
                        flag = true;
                        c[i][j] %= mod;
                    }
                }
            }
        }
        return c;
    }
    
    mat pow(mat a, ll n)
    {
        mat b(a.size(), vec(a.size()));
        for(int i=0; i<a.size(); ++ i)
            b[i][i] = 1;
        while(n > 0)
        {
            if(n & 1)
                b = mul(b, a);
            a = mul(a, a);
            n >>= 1;
        }
        return b;
    }
    
    void solve(int cases)
    {
        ll n, x, m, y, k;
        cin >> n >> x >> m >> y >> k;
    
        mat a(2, vec(2));
        a[0][0] = 1, a[0][1] = 1;
        a[1][0] = 1, a[1][1] = 0;
        flag = false;
        mat b(pow(a, n));
        mat c(mul(b, a));
        mat d(pow(a, m));
        mat e(mul(d, a));
    
        cout << "Case " << cases << ": ";
    
        if(flag || ((d[1][0] * x - b[1][0] * y) % (c[1][0] * d[1][0] - b[1][0] * e[1][0])) || ((c[1][0] * y - e[1][0] * x) % (c[1][0] * d[1][0] - e[1][0] * b[1][0])))
        {
            cout << "Impossible" << endl;
            return;
        }
    
        ll p = (c[1][0] * y - e[1][0] * x) / (c[1][0] * d[1][0] - e[1][0] * b[1][0]);
        ll q = (d[1][0] * x - b[1][0] * y) / (c[1][0] * d[1][0] - b[1][0] * e[1][0]);
    
        if(p < 0 || q < 0)
        {
            cout << "Impossible" << endl;
            return;
        }
    
        p %= mod;
        q %= mod;
    
        b = pow(a, k);
        c = mul(b, a);
    
        ll ans = ((p * b[1][0]) % mod + (q * c[1][0]) % mod) % mod;
        cout << ans << endl;
    }
    
    int main()
    {
        ios::sync_with_stdio(false);
        //freopen("out.txt", "w", stdout);
        int t;
        cin >> t;
        for(int i=1; i<=t; ++ i)
            solve(i);
        return 0;
    }
    
    
  • 相关阅读:
    二分图 洛谷P2055 [ZJOI2009]假期的宿舍
    并查集 洛谷P1640 [SCOI2010]连续攻击游戏
    贪心 洛谷P2870 Best Cow Line, Gold
    贪心 NOIP2013 积木大赛
    快速幂 NOIP2013 转圈游戏
    倍增LCA NOIP2013 货车运输
    树形DP 洛谷P2014 选课
    KMP UVA1328 Period
    动态规划入门 BZOJ 1270 雷涛的小猫
    KMP POJ 2752Seek the Name, Seek the Fame
  • 原文地址:https://www.cnblogs.com/aiterator/p/6849332.html
Copyright © 2011-2022 走看看