程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> FZU 1692 Key problem

FZU 1692 Key problem

編輯:C++入門知識

思路: 構造矩陣+矩陣快速冪 分析: 1 題目的意思是有n個人構成一個圈,每個人初始的有ai個蘋果,現在做m次的游戲,每一次游戲過後第i個人能夠增加R*A(i+n-1)%n+L*A(i+1)%n 個蘋果(題目有錯),問m輪游戲過後每個人的蘋果數 2 根據題目的意思我們能夠列出一輪過後每個人的蘋果數    a0 = a0+R*an-1+L*a1    a1 = a1+R*a0+L*a2    .............................    an-1 = an-1+R*an-2+L*a0 3 根據第二條思路我們可以構造出如下的矩陣    1 L 0 ...... R        a0         a0'    R 1 L .........  *     a1         a1'    ...................       ....      = ......     ...........R 1 L      an-2       an-2'    L ...........R 1      an-1       an-1' 4 那麼根據3我們可以利用矩陣快速冪求出最後的答案,但是題目的n最大為100,m最大為10^9,那麼每個case的時間復雜度為O(Logm*n^3),當n最大為100的時候是會TLE的 5 我們發現初始的矩陣裡面,矩陣是一個循環同構的,就是說矩陣的每一行度能夠從上一行推出,那麼我們只要利用O(n^2)的時間求出第一行,然後我們在利用遞推求出剩下的n-1行,那麼總的時間復雜度為O(Logm*n^2)   代碼:

/************************************************ 
 * By: chenguolin                               *  
 * Date: 2013-08-30                             * 
 * Address: http://blog.csdn.net/chenguolinblog * 
 ************************************************/  
#include<cstdio>  
#include<cstring>  
#include<iostream>  
#include<algorithm>  
using namespace std;  
  
typedef __int64 int64;  
const int N = 110;  
  
int arr[N];  
int n , m , L , R , MOD;  
  
struct Matrix{  
    int64 mat[N][N];  
    Matrix operator*(const Matrix& ma)const{  
        Matrix tmp;  
        for(int i = 0 ; i < n ; i++){  
            tmp.mat[0][i] = 0;   
            for(int j = 0 ; j < n ; j++)  
                tmp.mat[0][i] += mat[0][j]*ma.mat[j][i]%MOD;  
            tmp.mat[0][i] %= MOD;  
        }  
        for(int i = 1 ; i < n ; i++)  
            for(int j = 0 ; j < n ; j++)  
                tmp.mat[i][j] = tmp.mat[i-1][(j-1+n)%n];   
        return tmp;  
    }  
};  
  
void init(Matrix &ma){  
    memset(ma.mat , 0 , sizeof(ma.mat));  
    ma.mat[0][1] = L ; ma.mat[0][n-1] = R;  
    ma.mat[n-1][0] = L ; ma.mat[n-1][n-2] = R;  
    ma.mat[0][0] = ma.mat[n-1][n-1] = 1;  
    for(int i = 1 ; i < n-1 ; i++){  
        ma.mat[i][i-1] = R;  
        ma.mat[i][i+1] = L;  
        ma.mat[i][i] = 1;  
    }  
}  
  
void Pow(Matrix &ma){  
    Matrix ans;  
    memset(ans.mat , 0 , sizeof(ans.mat));  
    for(int i = 0 ; i < n ; i++)  
        ans.mat[i][i] = 1;  
    while(m){  
        if(m&1)  
            ans = ans*ma;  
        m >>= 1;  
        ma = ma*ma;  
    }  
    for(int i = 0 ; i < n ; i++){  
        int64 sum = 0;  
        for(int j = 0 ; j < n ; j++)  
            sum += ans.mat[i][j]*arr[j]%MOD;  
        if(i) printf(" ");  
        printf("%I64d" , sum%MOD);  
    }   
    puts("");  
}  
  
int main(){  
    int cas;  
    Matrix ma;  
    scanf("%d" , &cas);  
    while(cas--){  
        scanf("%d%d%d" , &n , &m , &L);   
        scanf("%d%d" , &R , &MOD);   
        for(int i = 0 ; i < n ; i++)  
            scanf("%d" , &arr[i]);  
        init(ma);  
        Pow(ma);  
    }  
    return 0;  
}  

 


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved