魔力手環(快速冪求解)


 

題目鏈接:https://www.nowcoder.com/questionTerminal/79c639e02bc94e6b919e3372c8e1dc5e

小易擁有一個擁有魔力的手環上面有n個數字(構成一個環),當這個魔力手環每次使用魔力的時候就會發生一種奇特的變化:每個數字會變成自己跟后面一個數字的和(最后一個數字的后面一個數字是第一個),一旦某個位置的數字大於等於100就馬上對100取模(比如某個位置變為103,就會自動變為3).現在給出這個魔力手環的構成,請你計算出使用k次魔力之后魔力手環的狀態。

輸入描述:
輸入數據包括兩行:
第一行為兩個整數n(2 ≤ n ≤ 50)和k(1 ≤ k ≤ 2000000000),以空格分隔
第二行為魔力手環初始的n個數,以空格分隔。范圍都在0至99.


輸出描述:
輸出魔力手環使用k次之后的狀態,以空格分隔,行末無空格。

 

輸入例子:
3 2
1 2 3

 

輸出例子:
8 9 7

思路:n個數的環進行移動相加,考慮到矩陣行、列變換可以完成這種移動和相加,於是構造出快速冪矩陣,快速冪矩陣M和原矩陣S相乘得到一次移動的結果,那么F(n+1) = M^n*S(這里的冪和乘法是矩陣的運算),很容易得到如下遞推示例:

 [[1 1 0] [0 1 1] [1 0 1]]*[[a][b][c]] = [[a+b][b+c][c+a]], 如此,已經確定了快速冪矩陣M,那么就要考慮如何相乘得到最快的冪求解速度。建議參看這篇博客

代碼如下:(算法復雜度為O(n^3*log(k)))

#include<iostream>
#include<cstring>
using namespace std;


int main(){
    int n,k;
    cin >> n >> k;
    int d[n];//存放結果
    for(int i=0;i<n;++i) {
        cin >> d[i];
    }
    //構造快速冪矩陣
    int Mul[n][n];
    for(int i=0;i<n-1;++i) {
        fill(Mul[i],Mul[i]+n,0);
        Mul[i][i] = 1;
        Mul[i][i+1] = 1;
    }
    fill(Mul[n-1],Mul[n-1]+n,0);
    Mul[n-1][0] = 1;
    Mul[n-1][n-1] = 1;
    //轉化為2進制,進行二分搜索
    while(k) {
        if(k&1) { 
            int temp[n];
            fill(temp, temp+n, 0);
            for(int i=0;i<n;++i) {
                for(int j=0;j<n;++j) {
                    temp[i] += (Mul[i][j]*d[j]);
                    temp[i] = temp[i]%100;
                }
            }
            memcpy(d, temp, sizeof(d));
        }
        k = k>>1;
        int temp[n][n];
        for(int i=0;i<n;++i) {
            fill(temp[i],temp[i]+n,0);
        }
        for(int i=0;i<n;++i) {
            for(int j=0;j<n;++j) {
                for(int k=0;k<n;++k) {
                    temp[i][j]+=Mul[i][k]*Mul[k][j];//二維矩陣相乘
                }
                temp[i][j] %= 100;//快速冪取余中,a^k % c =  (a % c)^k % c
            }
        }
        for(int i=0;i<n;++i) {
            memcpy(Mul[i],temp[i],sizeof(Mul[i]));
        }
    }
    //輸出結果
    for(int i=0;i<n-1;++i) {
        cout << d[i] << ' ';
    }
    cout << d[n-1] << endl;
    return 0;
}

 矩陣快速冪的總結(更多問題->熟練掌握)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM