Chieh's Blog

Because Of Coding

ZOJ Problem Set - 2317 Nice Patterns Strike Back

Chieh posted @ 2018年3月13日 23:13 in ZOJ , 305 阅读

飞机票http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1317

题意很清楚,就是给你n*m矩阵,求其中不包括2*2一样颜色的方案数ans%P

因为n很大,m很小,所以很容易想到肯定要对n进行一种特殊的处理。因为第i行和第i-1行的状态有关。所以可以用第i-1行的状态来求第i行,容易想到矩阵快速幂,但是矩阵的构造有点复杂,因为一行一共有2^m=t种状态,所以可以用状态压缩,则我们可以t*t的矩阵,其中matrix i_j表示第k行的状态和k+1行在状态为i和j的时候是否符合题意。现在我们就可以矩阵快速幂了,令A=[1,1....1]表示初始状态,则A*matrix为第二种状态,其中所有元素所和即为答案,所以第n中状态就是A*(matrix)^(n-1) 对后者进行矩阵快速幂,求出答案(用到java大数

import java.math.BigInteger;
import java.util.*;
public class Main {
	
	public static BigInteger two;
	public static int len;
	public static int P;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sca=new Scanner(System.in);
		int T=sca.nextInt();
		two=new BigInteger("2");
		while(T>0){
			T--;
			BigInteger n=sca.nextBigInteger();
			n=n.subtract(BigInteger.ONE);
			int m=sca.nextInt();
			 P=sca.nextInt();
			len=(int) Math.pow(2, m);
			if(n.compareTo(BigInteger.ZERO)==0){
				System.out.println(len);
				if(T!=0)
				System.out.println();
				continue;
			}
			Matrix a=new Matrix();
			for(int i=1;i<=len;i++){
				for(int j=1;j<=len;j++){
					int l=i-1;
					int r=j-1;
					String str1=Integer.toBinaryString(l);
					String str2=Integer.toBinaryString(r);
					while(str1.length()!=m)str1="0"+str1;
					while(str2.length()!=m)str2="0"+str2;
					str1="0"+str1;
					str2="0"+str2;
					boolean flag=true;
					for(int k=1;k<m;k++){
						int ok=1;
						if(str1.charAt(k)!=str1.charAt(k))ok=0;
						if(str1.charAt(k)!=str2.charAt(k))ok=0;
						if(str1.charAt(k)!=str1.charAt(k+1))ok=0;
						if(str1.charAt(k)!=str2.charAt(k+1))ok=0;
						if(ok==1){
							flag=false;
							break;
						}
						
					}
					if(flag){
						a.mat[i][j]=1;
					}
					else{
						a.mat[i][j]=0;
					}
				}
			}
			
				Matrix ans=Poww(a,n);
				int as=0;
				for(int i=1;i<=len;i++){
					for(int j=1;j<=len;j++){
						as=(as+ans.mat[i][j])%P;
					}
				}
				System.out.println(as);
				if(T!=0)
				System.out.println();
		}
	}
	public static Matrix MUL(Matrix a,Matrix b){
		Matrix c=new Matrix();
		for(int i=1;i<=len;i++){
			for(int j=1;j<=len;j++){
				for(int k=1;k<=len;k++){
					c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%P;
				}
			}
		}
		return c;
	}
	public static Matrix Poww(Matrix a,BigInteger b){
	    Matrix ans=new Matrix();
	    for(int i=1;i<=len;i++)ans.mat[i][i]=1;
	    while(b.compareTo(BigInteger.ZERO)!=0){
	        if(b.mod(two).compareTo(BigInteger.ONE)==0)
	        	ans=MUL(ans,a);
	        a=MUL(a, a);
	        b=b.divide(two);
	    }
	    return ans;
	}

}
class Matrix{
	public  int mat[][]=new int[35][35];
	public Matrix(){
		for(int i=1;i<=32;i++){
			for(int j=1;j<=32;j++){
				mat[i][j]=0;
			}
		}
	}
	 })

 


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter