设为首页 加入收藏

TOP

FZU 1692 Key problem
2014-11-23 21:42:23 来源: 作者: 【 】 浏览:7
Tags:FZU 1692 Key problem
思路: 构造矩阵+矩阵快速幂
分析:
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  
#include  
#include  
#include  
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;  
}  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇CF DIV.2 A. The Wall 下一篇HDU 4465 - Candy(概率与数学优..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·【C语言】动态内存管 (2025-12-27 06:23:20)
·C语言中的内存管理 - (2025-12-27 06:23:16)
·C语言指南:C语言内 (2025-12-27 06:23:14)
·Redis on AWS:Elast (2025-12-27 04:19:30)
·在 Spring Boot 项目 (2025-12-27 04:19:27)