题解

我们发现没有限制的小方格可以随便填

然后考虑有限制的,我们把它切割成一个个小块(枚举相邻的横纵坐标),然后记录一下这个小块的最大值限制(也就是所有覆盖它的矩形最小的最大值)

记录一下每个小块的大小,和每个小块在哪些有限制的大矩形,且小块的最大值限制等于大矩形的最大值限制,用一个二进制数表示

然后可以状压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」矩阵填数的更多相关文章

  1. loj2280 「FJOI2017」矩阵填数

    状压 dp.参考there #include <algorithm> #include <iostream> #include <cstring> #include ...

  2. 【BZOJ5010】【FJOI2017】矩阵填数 [状压DP]

    矩阵填数 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description 给定一个 h*w 的矩阵,矩阵的行 ...

  3. 「BZOJ 5010」「FJOI 2017」矩阵填数「状压DP」

    题意 你有一个\(h\times w\)的棋盘,你需要在每个格子里填\([1, m]\)中的某个整数,且满足\(n\)个矩形限制:矩形的最大值为某定值.求方案数\(\bmod 10^9+7\) \(h ...

  4. loj#2128. 「HAOI2015」数字串拆分 矩阵乘法

    目录 题目链接 题解 代码 题目链接 loj#2128. 「HAOI2015」数字串拆分 题解 \(f(s)\)对于\(f(i) = \sum_{j = i - m}^{i - 1}f(j)\) 这个 ...

  5. [FJOI2017]矩阵填数——容斥

    参考:题解 P3813 [[FJOI2017]矩阵填数] 题目大意: 给定一个 h∗w 的矩阵,矩阵的行编号从上到下依次为 1...h ,列编号从左到右依次 1...w . 在这个矩阵中你需要在每个格 ...

  6. P3813 [FJOI2017]矩阵填数(组合数学)

    P3813 [FJOI2017]矩阵填数 shadowice1984说:看到计数想容斥........ 这题中,我们把图分成若干块,每块的最大值域不同 蓝后根据乘法原理把每块的方案数(互不相干)相乘. ...

  7. [BZOJ5010][FJOI2017]矩阵填数(状压DP)

    5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 90  Solved: 45[Submit][Status][ ...

  8. bzoj5010: [Fjoi2017]矩阵填数

    Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...

  9. bzoj 5010: [Fjoi2017]矩阵填数

    Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...

随机推荐

  1. Codeforces Round #384 (Div. 2) A B C D dfs序+求两个不相交区间 最大权值和

    A. Vladik and flights time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  2. JSP2 特性

    JSP2 新特性 1.直接配置 JSP 属性 2.表达式语言 3.简化的自定义标签 API 4.Tag 文件语法 如果要使用 JSP2 语法,web.xml 文件必须使用 Servlet2.4 以上版 ...

  3. 跟我一起写Makefile(七)

    make 的运行—————— 一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的.但也有时你也许只想让make重编译某些文件,而不是 ...

  4. HTML+CSS基础小笔记再整理

    1. font的两个必须要写的:font-size 和 font-family text-indent 首行缩进(em)1em=一个文字大小 text-algin 对齐方式:left.center.r ...

  5. CF767 A. Snacktower 暴力

    LINK 题意:给出一个序列,如果存的数满足连续递减(第一个必须为n)则输出否则输出空行,并暂存当前数 思路:直接暴力不可行,由于待输出的数的个数满足单调性可以稍微优化,即从上一回输出的最小一个数开始 ...

  6. .NET Core get started on Ubuntu 14.04

    昨天.NET Core 1.0 正式发布了,所以尝尝鲜. 根据官方介绍页面的步骤: 步骤1. sudo sh -c 'echo "deb [arch=amd64] https://apt-m ...

  7. JWT 拓展

    JWT适用场景 https://www.jianshu.com/p/af8360b83a9f 适用于一次性操作的认证,颁布一个很短过期时间的JWT给浏览器. 无状态的JWT无法实现精确的在线人数统计. ...

  8. THINKPHP简单商品查询项目

    代码:http://files.cnblogs.com/files/wordblog/test.zip

  9. RTM,RTW,GA等软件版本号详解

    一直以来,对于新手而言,软件的版本号都是个比较困扰人的问题,什么Beta.RC,再来个RTM.RTW....头大了吧?RTM和RTW有什么区别?借此机会,就给大家介绍一下这方面的小知识吧. 1.软件开 ...

  10. shell读取文件的每一行内容并输出【转】

    写法一: #!/bin/bash while read line do echo $line done < file(待读取的文件) 写法二: #!/bin/bash cat file(待读取的 ...