• poj3233(Matrix Power Series)解题报告


    题目链接 : http://poj.org/problem?id=3233

    感觉做起来包含了矩阵的所有运算了,矩阵加法,矩阵乘法,矩阵快速幂,啊。。。写了好久

    题解 : k最大10^9,太大了,但经过观察可以折半计算,即 :

       当k是偶数,f[k] = f[k/2] * ( 1 + A^(k/2) )
        k是奇数,f[k] = f[k-1] + A^(k)

    AC代码加注释:

    #include<stdio.h>
    #include<algorithm>
    #include<string.h> 
    using namespace std;
    
    int A[32][32],N,m,sum[32][32]={0};
    
    void N_matrix(int (*p)[32],int (*a)[32],int (*b)[32],int N) //矩阵p=矩阵a*矩阵b 
    {	int temp[32][32];
    	int i,j,k;
    	memset(temp,0,sizeof(temp));
    	
    	for(i=0;i<N;i++)
    	for(j=0;j<N;j++)
    	for(k=0;k<N;k++)
    	temp[i][j]+=a[i][k]*b[k][j]%m;
    	
    	for(i=0;i<N;i++)
    	for(j=0;j<N;j++)
    	p[i][j]=temp[i][j]%m;
    }
    void N_matrixadd(int (*p)[32],int a[32][32],int b[32][32],int N) //矩阵p=矩阵a+矩阵b
    {	
    	
    	for(int i=0;i<N;i++)
    	for(int j=0;j<N;j++)
    	p[i][j]=(a[i][j]+b[i][j])%m;
    }
    void matrix_pow(int (*A)[32],int (*p)[32],int n,int N) //矩阵快速幂 ,n次方 
    {	int temp[32][32]={0},i=0,j=0;
    	
    	while(i<N)		//置为E矩阵 
    	{	temp[i][j]=1;
    		i++,j++; 
    		
    	}
    	for(i=0;i<N;i++)
    	for(j=0;j<N;j++)
    	p[i][j]=A[i][j];
    	
    	for(;n;n/=2)
    	{	if(n&1)
    		{	N_matrix(temp,temp,p,N);
    			
    		}
    		N_matrix(p,p,p,N);
    	}
    		for(int i=0;i<N;i++)
    		for(int j=0;j<N;j++)
    		p[i][j]=temp[i][j];  //将最终结果赋给p 
    }
    
    void digui(int k)
    {	int temp[32][32]={0};
    	
    	int y[32][32]={0};
    	if(k==1)
    	{	for(int i=0;i<N;i++)
    		for(int j=0;j<N;j++)
    		sum[i][j]=A[i][j];
    		return;
    	}
    			if(k&1)
    			{	
    				matrix_pow(A,y,k,N);
    				k--;
    			}
    		digui(k/2);
    		
    		N_matrixadd(temp,temp,sum,N);
    		
    		int x[32][32];
    		matrix_pow(A,x,k/2,N);
    
    		N_matrix(x,temp,x,N);
    		
    		N_matrixadd(temp,temp,x,N);
    		
    		N_matrixadd(temp,temp,y,N);
    		
    		for(int i=0;i<N;i++)
    		for(int j=0;j<N;j++)
    		sum[i][j]=temp[i][j];  //记录每一层递归最终结果 
    }
    
    int main()
    {	int k;
    	scanf("%d%d%d",&N,&k,&m);
    	for(int i=0;i<N;i++)
    		for(int j=0;j<N;j++)
    		scanf("%d",&A[i][j]);
    	digui(k);
    	
    	for(int i=0;i<N;i++)
    		{ 	printf("%d",sum[i][0]%m);
    			for(int j=1;j<N;j++)
    		 	printf(" %d",sum[i][j]%m);
    		
    			printf("
    ");
    		}
    	return 0;
    }
    

      

  • 相关阅读:
    shaderlab
    Unity
    Lua-闭包
    Unity- 小“东西”
    3.神经网络的保存、神经网络提取的2 ways
    2.搭建pytorch神经网络的常用两种方式
    搭建pytorch神经网络的常用两种方式
    1.建立第一个神经网络-关系拟合 (回归)
    python的编码解码问题
    github的搜素小技巧
  • 原文地址:https://www.cnblogs.com/lnu161403214/p/7854139.html
Copyright © 2020-2023  润新知