【LOJ】#2280. 「FJOI2017」矩阵填数
题解
我们发现没有限制的小方格可以随便填
然后考虑有限制的,我们把它切割成一个个小块(枚举相邻的横纵坐标),然后记录一下这个小块的最大值限制(也就是所有覆盖它的矩形最小的最大值)
记录一下每个小块的大小,和每个小块在哪些有限制的大矩形,且小块的最大值限制等于大矩形的最大值限制,用一个二进制数表示
然后可以状压dp了,每次枚举这个小块里面填不填最大值,填了就是\(V^{n} - (V - 1)^{n}\)不填就是\((V - 1)^{n}\)
代码
#include <bits/stdc++.h>
#define MAXN 500005
//#define ivorysi
#define enter putchar('\n')
#define space putchar(' ')
#define fi first
#define se second
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {putchar('-');x = -x;}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
const int MOD = 1000000007;
int T;
int N,H,W,Q,numx[45],numy[45],cnt,cov[505],cal[505],val[505],tot,ans;
int f[505][(1 << 10) + 5];
struct node {
int x1,x2,y1,y2,val;
}M[15];
int inc(int a,int b) {
a = a + b;
if(a >= MOD) a -= MOD;
return a;
}
int mul(int a,int b) {
return 1LL * a * b % MOD;
}
int fpow(int x,int c) {
int res = 1,t = x;
while(c) {
if(c & 1) res = mul(res,t);
t = mul(t,t);
c >>= 1;
}
return res;
}
void pre() {
sort(numx + 1,numx + cnt + 1);
sort(numy + 1,numy + cnt + 1);
memset(cov,0,sizeof(cov));
memset(cal,0,sizeof(cal));
tot = 0;
for(int i = 1 ; i <= cnt ; ++i) {
for(int j = 1 ; j <= cnt ; ++j) {
int sx = numx[i - 1] + 1,sy = numy[j - 1] + 1;
int tx = numx[i],ty = numy[j];
if(sx > tx || sy > ty) continue;
int v = Q;
bool flag = 0;
for(int k = 1 ; k <= N ; ++k) {
if(sx >= M[k].x1 && tx <= M[k].x2 && sy >= M[k].y1 && ty <= M[k].y2) {
v = min(v,M[k].val);
flag = 1;
}
}
if(!flag) {
ans = mul(ans,fpow(Q,(tx - sx + 1) * (ty - sy + 1)));
continue;
}
++tot;cal[tot] = (tx - sx + 1) * (ty - sy + 1);val[tot] = v;
for(int k = 1 ; k <= N ; ++k) {
if(v == M[k].val) {
if(sx >= M[k].x1 && tx <= M[k].x2 && sy >= M[k].y1 && ty <= M[k].y2) {
cov[tot] |= 1 << (k - 1);
}
}
}
}
}
}
void Solve() {
read(H);read(W);read(Q);read(N);
cnt = 0;
ans = 1;
for(int i = 1 ; i <= N ; ++i) {
read(M[i].x1);read(M[i].y1);read(M[i].x2);read(M[i].y2);read(M[i].val);
numx[++cnt] = M[i].x1 - 1;numy[cnt] = M[i].y1 - 1;
numx[++cnt] = M[i].x2;numy[cnt] = M[i].y2;
}
numx[++cnt] = 0;numy[cnt] = 0;
numx[++cnt] = H;numy[cnt] = W;
pre();
memset(f,0,sizeof(f));
f[0][0] = 1;
for(int i = 1 ; i <= tot ; ++i) {
for(int S = 0 ; S < (1 << N) ; ++S) {
f[i][S | cov[i]] = inc(f[i][S | cov[i]],mul(f[i - 1][S],inc(fpow(val[i],cal[i]),MOD - fpow(val[i] - 1,cal[i]))));
f[i][S] = inc(f[i][S],mul(f[i - 1][S],fpow(val[i] - 1,cal[i])));
}
}
ans = mul(ans,f[tot][(1 << N) - 1]);
out(ans);enter;
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
read(T);
while(T--) {
Solve();
}
return 0;
}
【LOJ】#2280. 「FJOI2017」矩阵填数的更多相关文章
- loj2280 「FJOI2017」矩阵填数
状压 dp.参考there #include <algorithm> #include <iostream> #include <cstring> #include ...
- 【BZOJ5010】【FJOI2017】矩阵填数 [状压DP]
矩阵填数 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一个 h*w 的矩阵,矩阵的行 ...
- 「BZOJ 5010」「FJOI 2017」矩阵填数「状压DP」
题意 你有一个\(h\times w\)的棋盘,你需要在每个格子里填\([1, m]\)中的某个整数,且满足\(n\)个矩形限制:矩形的最大值为某定值.求方案数\(\bmod 10^9+7\) \(h ...
- loj#2128. 「HAOI2015」数字串拆分 矩阵乘法
目录 题目链接 题解 代码 题目链接 loj#2128. 「HAOI2015」数字串拆分 题解 \(f(s)\)对于\(f(i) = \sum_{j = i - m}^{i - 1}f(j)\) 这个 ...
- [FJOI2017]矩阵填数——容斥
参考:题解 P3813 [[FJOI2017]矩阵填数] 题目大意: 给定一个 h∗w 的矩阵,矩阵的行编号从上到下依次为 1...h ,列编号从左到右依次 1...w . 在这个矩阵中你需要在每个格 ...
- P3813 [FJOI2017]矩阵填数(组合数学)
P3813 [FJOI2017]矩阵填数 shadowice1984说:看到计数想容斥........ 这题中,我们把图分成若干块,每块的最大值域不同 蓝后根据乘法原理把每块的方案数(互不相干)相乘. ...
- [BZOJ5010][FJOI2017]矩阵填数(状压DP)
5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 90 Solved: 45[Submit][Status][ ...
- bzoj5010: [Fjoi2017]矩阵填数
Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...
- bzoj 5010: [Fjoi2017]矩阵填数
Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...
随机推荐
- Codeforces Round #419 (Div. 2) A B C 暴力 区间更新技巧 +前缀和 模拟
A. Karen and Morning time limit per test 2 seconds memory limit per test 512 megabytes input standar ...
- 使用OAuth2.0协议的github、QQ、weibo第三方登录接入总结
目录 第三方接入总结 OAuth2.0介绍 github OAuth2.0登录接入 国内第三方应用商SDK使用 微博SDK 腾讯QQ SDK passport.js插件使用 安装 相关中间件.路由 返 ...
- select、poll和epoll多路I/O复用
一.三者的区别 select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被 ...
- SQL Server 2008如何开启数据库的远程连接
SQL Server 2008默认是不允许远程连接的,如果想要在本地用SSMS连接远程服务器上的SQL Server 2008,远程连接数据库.需要做两个部分的配置: 1,SQL Server Man ...
- HTTP、TCP、 UDP、 IP 、 Socket的关系
TCP和UDP协议是传输协议,IP是网络层协议.传输协议和网络层协议主要解决数据如何在网络中传输,或者说TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准.TCP负责发现传输 ...
- JSTL获取当日时间与数据时间比较
<jsp:useBean id="now" class="java.util.Date" /> <fmt:formatDate value=& ...
- 重构改善既有代码设计--重构手法06:Split Temporary Variable (分解临时变量)
你的程序有某个临时变量被赋值超过一次,它既不是循环变量,也不被用于收集计算结果.针对每次赋值,创造一个独立.对应的临时变量 double temp = 2 * (_height + _width); ...
- 【BZOJ】3495: PA2010 Riddle 2-SAT算法
[题意]有n个城镇被分成了k个郡,有m条连接城镇的无向边.要求给每个郡选择一个城镇作为首都,满足每条边至少有一个端点是首都.n,m,k<=10^6. [算法]2-SAT,前后缀优化建图 [题解] ...
- 使用infinite-scroll实现Ghost博文列表的滚动加载
Ghost博客系统默认提供的博文列表为传统的翻页方式(通过点击上一页.下一页等按钮来切换),随着移动客户端的发展,瀑布流式的滚动加载方式得到广泛应用,有效地提高了用户浏览信息的流畅度.下面详述如何通过 ...
- 42、和为S的两个数字
一.题目 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的. 二.解法 import java.util.ArrayLis ...