题目链接

BZOJ4000

题解

注意题目中的编号均从\(0\)开始= =

\(m\)特别小,考虑状压

设\(f[i][s]\)为第\(i\)行为\(s\)的方案数

每个棋子能攻击的只有本行,上一行,下一行,

我们能迅速找出哪些状态是合法的,以及每个状态所对应的上一行攻击位置的并和下一行攻击位置的并

如果两个状态上下相互攻击不到,就是合法的转移

我们弄一个\(2^m * 2^m\)的转移矩阵,就可以矩阵优化了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstring>
  5. #include<algorithm>
  6. #define uint unsigned int
  7. #define LL long long int
  8. #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
  9. #define REP(i,n) for (int i = 1; i <= (n); i++)
  10. #define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
  11. using namespace std;
  12. const int maxn = 65,maxm = 100005,INF = 1000000000;
  13. inline int read(){
  14. int out = 0,flag = 1; char c = getchar();
  15. while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
  16. while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
  17. return out * flag;
  18. }
  19. int s1,s2,s3,n,m,p,k;
  20. struct Matrix{
  21. uint s[maxn][maxn]; int n,m;
  22. Matrix(){memset(s,0,sizeof(s)); n = m = 0;}
  23. }A,F,Fn;
  24. inline Matrix operator *(const Matrix& a,const Matrix& b){
  25. Matrix c;
  26. if (a.m != b.n) return c;
  27. c.n = a.n; c.m = b.m;
  28. for (int i = 0; i < c.n; i++)
  29. for (int j = 0; j < c.m; j++)
  30. for (int k = 0; k < a.m; k++)
  31. c.s[i][j] += a.s[i][k] * b.s[k][j];
  32. return c;
  33. }
  34. inline Matrix qpow(Matrix a,int b){
  35. Matrix ans; ans.n = ans.m = a.n;
  36. for (int i = 0; i < ans.n; i++) ans.s[i][i] = 1;
  37. for (; b; b >>= 1,a = a * a)
  38. if (b & 1) ans = ans * a;
  39. return ans;
  40. }
  41. int f[maxn];
  42. bool check(int s){
  43. for (int i = 0; i < m; i++){
  44. if (s & (1 << i)){
  45. if (i + 1 >= p - k){
  46. if (s & (s2 << (i + 1 - (p - k)))) return false;
  47. }
  48. else if (s & (s2 >> ((p - k) - i - 1))) return false;
  49. }
  50. }
  51. return true;
  52. }
  53. int getu(int s){
  54. int re = 0;
  55. for (int i = 0; i < m; i++){
  56. if (s & (1 << i)){
  57. if (i + 1 >= p - k) re |= s1 << (i + 1 - (p - k));
  58. else re |= s1 >> ((p - k) - i - 1);
  59. }
  60. }
  61. return re;
  62. }
  63. int getd(int s){
  64. int re = 0;
  65. for (int i = 0; i < m; i++){
  66. if (s & (1 << i)){
  67. if (i + 1 >= p - k) re |= s3 << (i + 1 - (p - k));
  68. else re |= s3 >> ((p - k) - i - 1);
  69. }
  70. }
  71. return re;
  72. }
  73. void print(int x){
  74. for (int i = 4; i >= 0; i--)
  75. printf("%d",(x & (1 << i)) != 0);
  76. }
  77. int main(){
  78. n = read(); m = read();
  79. p = read(); k = read();
  80. REP(i,p) s1 = (s1 << 1) + read();
  81. REP(i,p){
  82. if (i == k + 1) s2 <<= 1,read();
  83. else s2 = (s2 << 1) + read();
  84. }
  85. REP(i,p) s3 = (s3 << 1) + read();
  86. int N = 1 << m;
  87. F.n = N; F.m = 1;
  88. for (int s = 0; s < N; s++)
  89. if (check(s)) F.s[s][0] = 1;
  90. A.n = A.m = N;
  91. for (int s = 0; s < N; s++){
  92. if (!check(s)) continue;
  93. for (int e = 0; e < N; e++){
  94. if (!check(e)) continue;
  95. int u = getu(s),d = getd(e);
  96. if (!(s & d) && !(e & u))
  97. A.s[s][e] = 1;
  98. }
  99. }
  100. Fn = qpow(A,n - 1) * F;
  101. uint ans = 0;
  102. for (int i = 0; i < N; i++) ans += Fn.s[i][0];
  103. cout << ans << endl;
  104. return 0;
  105. }

BZOJ4000 [TJOI2015]棋盘 【状压dp + 矩阵优化】的更多相关文章

  1. [BZOJ4000][TJOI2015]棋盘(状压DP+矩阵快速幂)

    题意极其有毒,注意给的行列都是从0开始的. 状压DP,f[i][S]表示第i行状态为S的方案数,枚举上一行的状态转移.$O(n2^{2m})$ 使用矩阵加速,先构造矩阵a[S1][S2]表示上一行为S ...

  2. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

  3. Codeforces 917C - Pollywog(状压 dp+矩阵优化)

    UPD 2021.4.9:修了个 typo,为啥写题解老出现 typo 啊( Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2900 的 D1C,不过还是被我想出来了 u1 ...

  4. 【BZOJ4000】【LOJ2104】【TJOI2015】棋盘 (状压dp + 矩阵快速幂)

    Description ​ 有一个\(~n~\)行\(~m~\)列的棋盘,棋盘上可以放很多棋子,每个棋子的攻击范围有\(~3~\)行\(~p~\)列.用一个\(~3 \times p~\)的矩阵给出了 ...

  5. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  6. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  7. 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法

    题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...

  8. 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra

    题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个 ...

  9. 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT

    题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...

随机推荐

  1. 2017.12.9 Java中的排序---冒泡排序、快速排序、选择排序

    //冒泡排序 public class demo{ public static void main(String[] args) { int[] sum={2,9,10,1,5,88}; System ...

  2. MAC 设置登录欢迎语

    MacdeMacBook-Pro:etc mac$ cd /etc MacdeMacBook-Pro:etc mac$ cat motd 技术沉淀,空杯心态! _______ _______ _ __ ...

  3. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第八节

    原文链接 第八节:利用CUDA函数库 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实验室进 ...

  4. SQL Server中Table字典数据的查询SQL示例代码

    SQL Server中Table字典数据的查询SQL示例代码 前言 在数据库系统原理与设计(第3版)教科书中这样写道: 数据库包含4类数据: 1.用户数据 2.元数据 3.索引 4.应用元数据 其中, ...

  5. MySQL DBA从小白到大神实战

    MySQL5.6 For CentOS 6.6 源码编译安装 o1.关闭防火墙o2.配置sysctl.confo3.检查操作系统上是否安装了MySQLo4.下载mysql源码包o5.添加用户和组o6. ...

  6. js中的||、&&与!用法

    &&和||在JQuery源代码内尤为使用广泛,由网上找了些例子作为参考,对其用法研究了一下: 1. && function a(){ alert("a&quo ...

  7. PowerDesigner导入Excel模板生成实体

        在Excel里整理好的表模型数据,可直接导入PowerDesigner.此功能通过PowerDesigner的脚本功能来实现,使用起来也简单.具体操作方法:     打开PowerDesign ...

  8. django+xadmin在线教育平台(二)

    老话总是没错的,工欲善其事,必先利其器 教你安装pycharm,mysql,navicat,python相关环境. windows下搭建开发环境 2-1 pycharm,mysql,Navicat安装 ...

  9. windows环境下安装npm、cnpm、bower

    什么是npm.cnpm.bower? 简单地说,就是帮你下载好你需要的css或者js库,而且三者功能也都是一样的.那为什么要下载这3个不同的呢?据说npm容易被墙……而cnpm是淘宝的镜像,所以通常用 ...

  10. 05.VUE学习之表达式

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...