• POJ 3233


    二分二分二分。。记录二分的点。1600多MS,应该 可以再优化

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    int stack[150],sp;
    int n,M;
    struct Matrax {
    	int m[35][35];
    };
    
    Matrax operator +( Matrax A, Matrax B){
    	Matrax ret;
    	for(int i=0;i<n;i++)
    	for(int j=0;j<n;j++)
    	ret.m[i][j]=(A.m[i][j]+B.m[i][j])%M;
    	return ret;
    }
    
    Matrax a,per;
    
    void initial(){
    	int i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			scanf("%d",&a.m[i][j]);
    			a.m[i][j]%=M;
    			per.m[i][j]=(i==j);
    		}
    	}
    }
    
    Matrax multi(Matrax a,Matrax b){
    	Matrax c;
    	int k,i,j;
    	for(i=0;i<n;i++){
    		for(j=0;j<n;j++){
    			c.m[i][j]=0;
    			for(k=0;k<n;k++){
    				c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%M;
    			}
    			c.m[i][j]%=M;
    		}
    	}
    	return c;
    }
    
    Matrax Power(int k){
    	Matrax c,p,ans=per;
    	p=a;
    	while(k){
    		if(k&1){
    			ans=multi(ans,p);
    			k--;
    		}
    		else {
    			k/=2;
    			p=multi(p,p);
    		}
    	}
    /*	for(int i=0;i<n;i++){
    	for(int j=0;j<n;j++)
    	cout<<' '<<ans.m[i][j];
    	cout<<endl;
    	}*/
    	return ans;
    }
    
    int main(){
    	int k;
    	while(scanf("%d%d%d",&n,&k,&M)!=EOF){
    		initial();
    		sp=-1;
    		stack[++sp]=k;
    		while(k!=1){
    			if(k%2){
    				k--;
    				stack[++sp]=k;
    			}
    			else{
    			stack[++sp]=k/2;
    			k/=2;
    			}
    		}
    /*		for(int i=0;i<=sp;i++)
    		cout<<stack[i]<<' ';
    		cout<<endl;*/
    		Matrax ans=a;
    		for(int i=sp;i>=1;i--){
    			if(stack[i]+1==stack[i-1]){
    				ans=ans+Power(stack[i-1]);
    			}
    			else if(stack[i]*2==stack[i-1]){
    				ans=ans+multi(ans,Power(stack[i]));
    			}
    	/*				for(int s=0;s<n;s++){
    			printf("%d",ans.m[s][0]%M);
    			for(int t=1;t<n;t++)
    			printf(" %d",ans.m[s][t]%M);
    			printf("
    ");
    		}*/
    		}
    		for(int s=0;s<n;s++){
    			printf("%d",ans.m[s][0]%M);
    			for(int t=1;t<n;t++)
    			printf(" %d",ans.m[s][t]%M);
    			printf("
    ");
    		}
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    单例对象
    G1回收算法
    Java锁
    VUE开发
    Java线程池
    Java线程状态
    什么是进程,什么是线程
    maven 常用命令
    linux启动脚本,暂停脚本
    delphi---控件使用
  • 原文地址:https://www.cnblogs.com/jie-dcai/p/3946578.html
Copyright © 2020-2023  润新知