BZOJ4000 [TJOI2015]棋盘 【状压dp + 矩阵优化】
题目链接
题解
注意题目中的编号均从\(0\)开始= =
\(m\)特别小,考虑状压
设\(f[i][s]\)为第\(i\)行为\(s\)的方案数
每个棋子能攻击的只有本行,上一行,下一行,
我们能迅速找出哪些状态是合法的,以及每个状态所对应的上一行攻击位置的并和下一行攻击位置的并
如果两个状态上下相互攻击不到,就是合法的转移
我们弄一个\(2^m * 2^m\)的转移矩阵,就可以矩阵优化了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define uint unsigned int
#define LL long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 65,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int s1,s2,s3,n,m,p,k;
struct Matrix{
uint s[maxn][maxn]; int n,m;
Matrix(){memset(s,0,sizeof(s)); n = m = 0;}
}A,F,Fn;
inline Matrix operator *(const Matrix& a,const Matrix& b){
Matrix c;
if (a.m != b.n) return c;
c.n = a.n; c.m = b.m;
for (int i = 0; i < c.n; i++)
for (int j = 0; j < c.m; j++)
for (int k = 0; k < a.m; k++)
c.s[i][j] += a.s[i][k] * b.s[k][j];
return c;
}
inline Matrix qpow(Matrix a,int b){
Matrix ans; ans.n = ans.m = a.n;
for (int i = 0; i < ans.n; i++) ans.s[i][i] = 1;
for (; b; b >>= 1,a = a * a)
if (b & 1) ans = ans * a;
return ans;
}
int f[maxn];
bool check(int s){
for (int i = 0; i < m; i++){
if (s & (1 << i)){
if (i + 1 >= p - k){
if (s & (s2 << (i + 1 - (p - k)))) return false;
}
else if (s & (s2 >> ((p - k) - i - 1))) return false;
}
}
return true;
}
int getu(int s){
int re = 0;
for (int i = 0; i < m; i++){
if (s & (1 << i)){
if (i + 1 >= p - k) re |= s1 << (i + 1 - (p - k));
else re |= s1 >> ((p - k) - i - 1);
}
}
return re;
}
int getd(int s){
int re = 0;
for (int i = 0; i < m; i++){
if (s & (1 << i)){
if (i + 1 >= p - k) re |= s3 << (i + 1 - (p - k));
else re |= s3 >> ((p - k) - i - 1);
}
}
return re;
}
void print(int x){
for (int i = 4; i >= 0; i--)
printf("%d",(x & (1 << i)) != 0);
}
int main(){
n = read(); m = read();
p = read(); k = read();
REP(i,p) s1 = (s1 << 1) + read();
REP(i,p){
if (i == k + 1) s2 <<= 1,read();
else s2 = (s2 << 1) + read();
}
REP(i,p) s3 = (s3 << 1) + read();
int N = 1 << m;
F.n = N; F.m = 1;
for (int s = 0; s < N; s++)
if (check(s)) F.s[s][0] = 1;
A.n = A.m = N;
for (int s = 0; s < N; s++){
if (!check(s)) continue;
for (int e = 0; e < N; e++){
if (!check(e)) continue;
int u = getu(s),d = getd(e);
if (!(s & d) && !(e & u))
A.s[s][e] = 1;
}
}
Fn = qpow(A,n - 1) * F;
uint ans = 0;
for (int i = 0; i < N; i++) ans += Fn.s[i][0];
cout << ans << endl;
return 0;
}
BZOJ4000 [TJOI2015]棋盘 【状压dp + 矩阵优化】的更多相关文章
- [BZOJ4000][TJOI2015]棋盘(状压DP+矩阵快速幂)
题意极其有毒,注意给的行列都是从0开始的. 状压DP,f[i][S]表示第i行状态为S的方案数,枚举上一行的状态转移.$O(n2^{2m})$ 使用矩阵加速,先构造矩阵a[S1][S2]表示上一行为S ...
- BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )
状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...
- Codeforces 917C - Pollywog(状压 dp+矩阵优化)
UPD 2021.4.9:修了个 typo,为啥写题解老出现 typo 啊( Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2900 的 D1C,不过还是被我想出来了 u1 ...
- 【BZOJ4000】【LOJ2104】【TJOI2015】棋盘 (状压dp + 矩阵快速幂)
Description 有一个\(~n~\)行\(~m~\)列的棋盘,棋盘上可以放很多棋子,每个棋子的攻击范围有\(~3~\)行\(~p~\)列.用一个\(~3 \times p~\)的矩阵给出了 ...
- HDU 5434 Peace small elephant 状压dp+矩阵快速幂
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant Accepts: 38 Submissions: ...
- 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂
[题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...
- 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法
题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...
- 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra
题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个 ...
- 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT
题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...
随机推荐
- 2017.12.9 Java中的排序---冒泡排序、快速排序、选择排序
//冒泡排序 public class demo{ public static void main(String[] args) { int[] sum={2,9,10,1,5,88}; System ...
- MAC 设置登录欢迎语
MacdeMacBook-Pro:etc mac$ cd /etc MacdeMacBook-Pro:etc mac$ cat motd 技术沉淀,空杯心态! _______ _______ _ __ ...
- CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第八节
原文链接 第八节:利用CUDA函数库 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实验室进 ...
- SQL Server中Table字典数据的查询SQL示例代码
SQL Server中Table字典数据的查询SQL示例代码 前言 在数据库系统原理与设计(第3版)教科书中这样写道: 数据库包含4类数据: 1.用户数据 2.元数据 3.索引 4.应用元数据 其中, ...
- MySQL DBA从小白到大神实战
MySQL5.6 For CentOS 6.6 源码编译安装 o1.关闭防火墙o2.配置sysctl.confo3.检查操作系统上是否安装了MySQLo4.下载mysql源码包o5.添加用户和组o6. ...
- js中的||、&&与!用法
&&和||在JQuery源代码内尤为使用广泛,由网上找了些例子作为参考,对其用法研究了一下: 1. && function a(){ alert("a&quo ...
- PowerDesigner导入Excel模板生成实体
在Excel里整理好的表模型数据,可直接导入PowerDesigner.此功能通过PowerDesigner的脚本功能来实现,使用起来也简单.具体操作方法: 打开PowerDesign ...
- django+xadmin在线教育平台(二)
老话总是没错的,工欲善其事,必先利其器 教你安装pycharm,mysql,navicat,python相关环境. windows下搭建开发环境 2-1 pycharm,mysql,Navicat安装 ...
- windows环境下安装npm、cnpm、bower
什么是npm.cnpm.bower? 简单地说,就是帮你下载好你需要的css或者js库,而且三者功能也都是一样的.那为什么要下载这3个不同的呢?据说npm容易被墙……而cnpm是淘宝的镜像,所以通常用 ...
- 05.VUE学习之表达式
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...