BZOJ 4031: [HEOI2015]小Z的房间 (矩阵树定理 板题)
背结论 : 度-邻
CODE1
O(n3logn)O(n^3logn)O(n3logn)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template<class T>inline void read(T &num) {
register char ch; register int flg = 1;
while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(num=0; isdigit(ch); num=num*10+ch-'0', ch=getchar());
num *= flg;
}
const int MAXN = 85;
const int mod = 1e9;
int n, m, tot, id[10][10];
int a[MAXN][MAXN], d[MAXN][MAXN], g[MAXN][MAXN];
char s[10];
inline void link(int u, int v) {
++d[u][u], ++d[v][v];
++g[u][v], ++g[v][u];
}
inline int Gauss(int N) { //高斯消元成上三角
int ans = 1;
for(int i = 1; i <= N; ++i) {
for(int k = i+1; k <= N; ++k)
while(a[k][i]) { //这里有一个log
int d = a[i][i] / a[k][i];
for(int j = i; j <= N; ++j)
a[i][j] = ((a[i][j] - 1ll * d * a[k][j] % mod) % mod + mod) % mod;
swap(a[i], a[k]), ans = -ans; //注意每交换两行都要取反
}
ans = (1ll * ans * a[i][i] % mod + mod) % mod;
}
return ans;
}
int main() {
read(n), read(m);
for(int i = 1; i <= n; ++i) {
scanf("%s", s+1);
for(int j = 1; j <= m; ++j)
if(s[j] != '*') {
id[i][j] = ++tot;
if(id[i-1][j]) link(tot, id[i-1][j]);
if(id[i][j-1]) link(tot, id[i][j-1]);
}
}
for(int i = 1; i < tot; ++i)
for(int j = 1; j < tot; ++j)
a[i][j] = d[i][j] - g[i][j];
printf("%d\n", (Gauss(tot-1) + mod) % mod);
}
CODE2
O(n3+n2logn)→O(n3)O(n^3+n^2logn)\to O(n^3)O(n3+n2logn)→O(n3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template<class T>inline void read(T &num) {
register char ch; register int flg = 1;
while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
for(num=0; isdigit(ch); num=num*10+ch-'0', ch=getchar());
num *= flg;
}
const int MAXN = 85;
const int mod = 1e9;
int n, m, tot, id[10][10];
int a[MAXN][MAXN], d[MAXN][MAXN], g[MAXN][MAXN];
char s[10];
inline void link(int u, int v) {
++d[u][u], ++d[v][v];
++g[u][v], ++g[v][u];
}
inline void kill(int a, int b, int &ii, int &ik, int &ki, int &kk, int &sign) {
ii = 1, ik = 0;
ki = 0, kk = 1;
sign = 1;
while(b) {
(ii -= a/b * ki) %= mod;
(ik -= a/b * kk) %= mod;
a -= a/b * b;
swap(a, b);
swap(ii, ki);
swap(ik, kk);
sign = -sign;
}
}
inline int Gauss(int N) {
int ans = 1, ii, ik, ki, kk, sign;
for(int i = 1; i <= N; ++i) {
for(int k = i+1; k <= N; ++k) if(a[k][i]) {
kill(a[i][i], a[k][i], ii, ik, ki, kk, sign); //先把系数算出来
ans *= sign;
for(int j = i; j <= N; ++j) {
int _aij = (1ll * a[i][j] * ii + 1ll * a[k][j] * ik) % mod;
int _akj = (1ll * a[i][j] * ki + 1ll * a[k][j] * kk) % mod;
a[i][j] = _aij, a[k][j] = _akj;
}
}
ans = 1ll * ans * a[i][i] % mod;
}
return ans;
}
int main() {
read(n), read(m);
for(int i = 1; i <= n; ++i) {
scanf("%s", s+1);
for(int j = 1; j <= m; ++j)
if(s[j] != '*') {
id[i][j] = ++tot;
if(id[i-1][j]) link(tot, id[i-1][j]);
if(id[i][j-1]) link(tot, id[i][j-1]);
}
}
for(int i = 1; i < tot; ++i)
for(int j = 1; j < tot; ++j)
a[i][j] = d[i][j] - g[i][j];
printf("%d\n", (Gauss(tot-1) + mod) % mod);
}
BZOJ 4031: [HEOI2015]小Z的房间 (矩阵树定理 板题)的更多相关文章
- BZOJ 4031: [HEOI2015]小Z的房间 [矩阵树定理 行列式取模]
http://www.lydsy.com/JudgeOnline/problem.php?id=4031 裸题........ 问题在于模数是$10^9$ 我们发现消元的目的是让一个地方为0 辗转相除 ...
- 【bzoj4031】[HEOI2015]小Z的房间 矩阵树定理
题目描述 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. 你想要打通一 ...
- bzoj4031 [HEOI2015]小Z的房间——矩阵树定理
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4031 矩阵树定理的模板题(第一次的矩阵树定理~): 有点细节,放在注释里了. 代码如下: # ...
- BZOJ 4031 [HEOI2015]小Z的房间(Matrix-Tree定理)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4031 [题目大意] 你突然有了一个大房子,房子里面有一些房间. 事实上,你的房子可以看 ...
- BZOJ.4031.[HEOI2015]小Z的房间(Matrix Tree定理 辗转相除)
题目链接 辗转相除解行列式的具体实现? 行列式的基本性质. //864kb 64ms //裸的Matrix Tree定理.练习一下用辗转相除解行列式.(因为模数不是质数,所以不能直接乘逆元来高斯消元. ...
- [HEOI2015]小Z的房间(矩阵树定理学习笔记)
题目描述 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. 你想要打通一 ...
- [HEOI2015] 小Z的房间 - 矩阵树定理
#include <bits/stdc++.h> using namespace std; #define int long long const int N = 105; const i ...
- bzoj 4031: 小Z的房间 矩阵树定理
bzoj 4031: 小Z的房间 矩阵树定理 题目: 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时 ...
- bzoj 4031: [HEOI2015]小Z的房间 轮廓线dp
4031: [HEOI2015]小Z的房间 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 98 Solved: 29[Submit][Status] ...
随机推荐
- SGI STL源码stl_vector.h分析
前言 vector 是最常用的 C++ 容器,其动态扩容的特性是普通数组不具备的,这大大增加了编程的灵活性.虽然平时用 vector 很多,也能基本理解其原理,但无法从深层次理解.直到研读了 vect ...
- SQLite进阶-10.约束
约束 约束是作用于数据表中列上的规则,用于限制表中数据的类型.约束的存在保证了数据库中数据的精确性和可靠性. 约束可以是列级或表级,列级约束作用于单一的列,而表级约束作用于整张数据表. SQLite中 ...
- 史上最全的MySQL高性能优化实战总结!
1.1 前言 MySQL对于很多Linux从业者而言,是一个非常棘手的问题,多数情况都是因为对数据库出现问题的情况和处理思路不清晰.在进行MySQL的优化之前必须要了解的就是MySQL的查询过程,很多 ...
- cent0S 设置静态ip
TYPE=EthernetPROXY_METHOD=noneBROWSER_ONLY=noBOOTPROTO=static # static ip,#BOOTPROTO=dhcp # dynamic ...
- Java进阶开发-基于Base64的加密与解密操作
基于Base64的加密与解密操作 正常来讲加密基本上永远伴随着解密,所谓的加密或者解密往往都是需要有一些所谓的规则.在JDK1.8开始提供有一组新的加密处理操作,Base64处理.在这个类里面有两个内 ...
- Django: ORM 数据库设置和读写分离
一.Django的数据库配置 (一)修改settings.py文件关于数据库的配置: Django默认使用sqlite: # Django默认的数据库库,SQLit配置 DATABASES = { ' ...
- Springboot Hikari Centos 首次连数据库很慢
前言: springboot项目默认使用了hikari作为数据库连接池,在开发机器上一切正常. 但是把程序部署到Centos7 x64上之后发现,每次首页登录的时候都要停顿几十秒. 于是,在程序启动后 ...
- MySQL之常用查询
1) 查询字符集 show variables like 'character%'; 2)查看版本 select version(); 3) 共享表空间的数据文件存储路径 show variables ...
- 闭包问题for(var i=0;i<10;i++){ setTimeout(function(){ console.log(i)//10个10 },1000) }
for(var i=0;i<10;i++){ setTimeout(function(){ console.log(i)//10个10 },1000) } 遇到这种问题 如何用解决呢 for(v ...
- TVM设备添加以及代码生成
因为要添加的设备是一种类似于GPU的加速卡,TVM中提供了对GPU编译器的各种支持,有openCl,OpenGL和CUDA等,这里我们选取比较熟悉的CUDA进行模仿生成.从总体上来看,TVM是一个多层 ...