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\)次修 ...
随机推荐
- JSON对象转成formData对象,formData对象转成JSON对象
在向后端请求时,如果上传的数据里存在file文件对象,需要用到表单提交,这时候我们需要将JSON对象,转成formData对象,具体见代码 const formData = new FormData( ...
- OneNote- 面经
- 阿里云服务器下安装LAMP环境(CentOS Linux 6.3) 安装与配置 php
下面我们一起为服务器安装 PHP,在使用 yum 安装软件包的时候,yum 会去默认的资源库里查看我们要安装的软件包,然后到指定的服务器上下载并安装. 但是有的时候,我们要安装的软件包并没有包含在默认 ...
- HTML复选框checkbox默认样式修改
此方法可以将复选框的默认样式替换成任意样式.如图: 未选择: 选择时: 思路:将复选框隐藏,利用lebal元素的焦点传递特性,用lebal的样式替代复选框. 代码如下: <!DOCTYPE ht ...
- SAP 日志管理
现在项目上自开发的dialog程序越来越多,有很多敏感数据需要像SAP标准的业务一样,能看到所有的修改日志,要想实现日志的功能,有以下几个办法: 办法一.建一个日志表,在原有表的基础上,加上日期和时间 ...
- Apache 配置默认编码
找到apache配置文件 httpd.conf ,找到以下内容 # # Specify a default charset for all content served; this enables # ...
- Mysql--7种Join查询
0.sql的执行顺序 手写顺序 机读顺序 总结 ①From:对from左边的表和右边的表计算笛卡尔积,产生虚拟表c1 ②On:对c1中的数据进行on过滤,只有符合过滤条件的数据记录才会记录在虚拟表c2 ...
- Javascript 模块化指北
前言 随着 Web 技术的蓬勃发展和依赖的基础设施日益完善,前端领域逐渐从浏览器扩展至服务端(Node.js),桌面端(PC.Android.iOS),乃至于物联网设备(IoT),其中 JavaScr ...
- PHP array_multisort()函数超详细理解
项目中用到这个函数了 ,起初对这个函数一直是懵逼状态,文档都看的朦朦胧胧的 网上无意间看到这篇文章 ,写的超级详细,收藏了 . 当然要先放原地址:https://www.cnblogs.com/WuN ...
- JZOJ 3385. 【NOIP2013模拟】黑魔法师之门
3385. [NOIP2013模拟]黑魔法师之门 (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB Detailed Limi ...