zoj 2317 Nice Patterns Strike Back(矩阵乘法)
problemId=1317">http://acm.zju.edu.cn/onlinejudge/showProblem.do? problemId=1317
给出一个n*m的矩阵(n <= 10^100, m <= 5),对于2*2的子方格若全是黑色或全是白色的是非法的,用黑白两色去染n*m的方格,问共同拥有多少种合法的染色方案。
构造出转移矩阵,上一行向下一行的转移矩阵。由于m<=5,每行最多有32个状态。能够进行状态压缩构造出一个32*32的转移矩阵A。A[i][j] = 1表示上一行i状态能够向下一行的j状态转移。否则不能转移。要求最后的合法方案数,就再构造一个B矩阵,是一个32*1的矩阵,表示了到达第一行每个状态的方案数。那么A*B就表示到达第二行每个状态的方案数。以此类推。A^n-1 * B表示到达第n行每个状态的合法方案数,那么全部状态相应方案数的和就是总的方案数。
由于n特别大。要用到大数。我存矩阵的时候開始定义的大数类,一直T。改成了int型才A,1s+,难道大数类这么慢么,5s都过不了。
import java.io.*;
import java.math.BigInteger;
import java.util.Scanner; class Matrix
{
public int [][] mat = new int[35][35];
public Matrix()
{ }
public void init()
{
for(int i = 0; i < 35; i++)
{
for(int j = 0; j < 35; j++)
{
if(i == j)
mat[i][j] = 1;
else mat[i][j] = 0;
}
}
}
} public class Main {
public static Matrix A,B,res;
public static BigInteger n;
public static int m,p,test,mm;
static Scanner cin = new Scanner(System.in); public static void buildA()
{
for(int i = 0; i < mm; i++)
{
for(int j = 0; j < mm; j++)
{
String s1 = Integer.toBinaryString(i);
String s2 = Integer.toBinaryString(j);
String ss1 = new String();
String ss2 = new String();
for(int k = 0; k < m-s1.length(); k++)
ss1 += '0';
ss1 += s1;
for(int k = 0; k < m-s2.length(); k++)
ss2 += '0';
ss2 += s2; int flag = 0;
for(int k = 0; k < m-1; k++)
{
if(ss1.charAt(k)-'0' == 0 && ss1.charAt(k+1)-'0' == 0
&& ss2.charAt(k)-'0' == 0 && ss2.charAt(k+1)-'0' == 0)
{flag = 1;break;}
if(ss1.charAt(k)-'0' == 1 && ss1.charAt(k+1)-'0' == 1
&& ss2.charAt(k)-'0' == 1 && ss2.charAt(k+1)-'0' == 1)
{flag = 1;break;}
}
if(flag == 1)
A.mat[i][j] = 0;
else A.mat[i][j] = 1;
}
}
} public static Matrix Mul(Matrix x,Matrix y)
{
Matrix ans = new Matrix();
for(int i = 0; i < mm; i++)
{
for(int k = 0; k < mm; k++)
{
if(x.mat[i][k] == 0)
continue;
for(int j = 0; j < mm; j++)
{
ans.mat[i][j] = (ans.mat[i][j]+x.mat[i][k]*y.mat[k][j])%p;
}
}
}
return ans;
} public static Matrix Pow(Matrix tmp,BigInteger nn)
{
Matrix ans = new Matrix();
ans.init();
while(nn.compareTo(BigInteger.ZERO) > 0)
{
if( nn.remainder(BigInteger.valueOf(2)).compareTo(BigInteger.ONE) == 0)
ans = Mul(ans,tmp);
nn = nn.divide(BigInteger.valueOf(2));
tmp = Mul(tmp,tmp);
}
return ans;
} public static void main(String[] args) throws IOException
{
int test = cin.nextInt();
while((test--) > 0)
{
n = cin.nextBigInteger();
m = cin.nextInt();
p = cin.nextInt();
mm = (1<<m); A = new Matrix();
B = new Matrix(); buildA();
for(int i = 0; i < mm; i++)
B.mat[i][0] = 1; res = Pow(A,n.subtract(BigInteger.ONE));
res = Mul(res,B); int anw = 0;
for(int i = 0; i < mm; i++)
{
anw = (anw+res.mat[i][0])%p;
}
System.out.println(anw);
if(test > 0)
System.out.println();
}
}
}
zoj 2317 Nice Patterns Strike Back(矩阵乘法)的更多相关文章
- ZOJ - 3216:Compositions (DP&矩阵乘法&快速幂)
We consider problems concerning the number of ways in which a number can be written as a sum. If the ...
- ZOJ2317-Nice Patterns Strike Back:矩阵快速幂,高精度
Nice Patterns Strike Back Time Limit: 20000/10000MS (Java/Others)Memory Limit: 128000/64000KB (Java/ ...
- ZOJ 2671 Cryptography 矩阵乘法+线段树
B - Cryptography Time Limit:5000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Subm ...
- ZOJ 3256 Tour in the Castle 插头DP 矩阵乘法
题解 这题是一道非常好的插头题,与一般的按格转移的题目不同,由于m很大,要矩阵乘法,这题需要你做一个按列转移的插头DP. 按列转移多少与按格转移不同,但大体上还是基于连通性进行转移.每一列只有右插头是 ...
- *HDU2254 矩阵乘法
奥运 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submissi ...
- *HDU 1757 矩阵乘法
A Simple Math Problem Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- CH Round #30 摆花[矩阵乘法]
摆花 CH Round #30 - 清明欢乐赛 背景及描述 艺术馆门前将摆出许多花,一共有n个位置排成一排,每个位置可以摆花也可以不摆花.有些花如果摆在相邻的位置(隔着一个空的位置不算相邻),就不好看 ...
- POJ3070 Fibonacci[矩阵乘法]
Fibonacci Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13677 Accepted: 9697 Descri ...
- bzoj 2738 矩阵乘法
其实这题跟矩阵乘法没有任何卵关系,直接整体二分,用二维树状数组维护(刚刚学会>_<),复杂度好像有点爆炸(好像有十几亿不知道是不是算错了),但我们不能怂啊23333. #include&l ...
随机推荐
- CSS常用原子类base.css
在写css文件时,一些常用的属性我们完全可以把它单独提出来,提高复用性,能增加开发效率,下面是一些网站推荐的常用原子类,也是零度逍遥常用的,规定了一些字体,内外边距和宽高属性,一般写在base.css ...
- python3.x学习笔记2(基础知识)
1.元组元组其实跟列表差不多,也是存一组数,只是它一旦创建,便不能在修改,所以又叫只读列表语法:names =('shgd','sjdh') 它只有两个方法,一个是count,一个是index 2.字 ...
- ListView中嵌套GridView点击事件
做一个项目时,需要在ListView中嵌套GridView,因为ListView的每个条目中不一定出现GridView,那么问题来了,添加GridView的Item的点击事件后,有GridView出现 ...
- 增强for循环的使用详解及代码
首先说一下他的语法结构: for(数据类型 变量 :集合){ //这里写要遍历的元素,或者所需要的代码即可//如果集合中存放的是对象,可以获取到每个对象(数据类型=对象类型 变量(遍历出来的每个对象) ...
- codeforces 404 B Marathon【fmod对浮点数取余】
题意:给出一个边长为a的正方形,给出d,给出n,输出走得距离为i个d的时候的坐标 学习的这一篇 http://blog.csdn.net/synapse7/article/details/215956 ...
- 禁用cache
Z:\src\services\network\network_context.cc:http_cache_enabled
- Linux和Windows系统的远程桌面访问知识(转载)
为新手讲解Linux和Windows系统的远程桌面访问知识 很多新手都是使用Linux和Windows双系统的,它们之间的远程桌面访问是如何连接的,我们就为新手讲解Linux和Windows系统的 ...
- ArcGIS api for javascript——创建地图
描述 这个示例显示ArcGIS Server的一个地图.ArcGIS Server地图是缓存的,意味着它有服务器管理员建来提升性能的一组预先渲染的切片.由于这个原因地图通过ArcGISTiledMap ...
- Liquibase被锁
经常运行过程中出现 Liquibase - Waiting for changelog lock Waiting for changelog lock.... Running the migratio ...
- openGl超级宝典学习笔记 (2) 7个主要的几何图元
点(GL_POINTS): 点总是正方形的像素,默认情况下,点的大小不受透视除法影响. 即无论与视点的距离怎样,它的大小都不改变.为了获得圆点.必须在抗锯齿模式下绘制点. 能够用glPointSize ...