【BZOJ5010】【FJOI2017】矩阵填数 [状压DP]
矩阵填数
Time Limit: 10 Sec Memory Limit: 128 MB
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
3 3 2 2
1 1 2 2 2
2 2 3 3 1
4 4 4 4
1 1 2 3 3
2 3 4 4 2
2 1 4 3 2
1 2 3 4 4
Sample Output
76475
HINT
Main idea
给定一个矩阵,要求若干个子矩阵中最大值必须为Val,询问方案数。
Solution
显然我们想到了状压DP,令 f[i][j] 表示做到了第i个块状态为j的方案,j表示哪些块满足限制。
由于子矩阵限制可能会重叠,所以我们先预处理,将矩阵分为若干个小块,每个小块中仅有一个限制条件(显然就是所有覆盖条件中最小的一个)。
然后我们记 Val 表示这一块里面的限制值,Num 表示这一块的个数,然后我们再记个 op 表示覆盖哪些块的限制值为Val。
之后用状压DP,考虑第 i 块是否取限制值,取则方案数为 (Val - 1) ^ Num,不取则方案数为 Val ^ Num - (Val - 1) ^ Num。
当取限制值时,把对应方案数转移到 f[i + 1][j | op[i + 1]],否则转移到 f[i + 1][j]。最后答案就是 f[cnt][all] 了。
Code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<map>
using namespace std;
typedef long long s64; const int ONE=;
const int MOD=1e9+;
const int INF=; int T;
int h,w,m,n,all;
int qx[ONE],x_num,qy[ONE],y_num;
int Num[ONE],Val[ONE],op[ONE],cnt;
int f[ONE][]; struct power
{
int x1,y1;
int x2,y2;
int val;
}a[ONE]; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} s64 Quick(s64 a,int b)
{
s64 res=;
while(b)
{
if(b&) res=res*a%MOD;
a=(s64)a*a%MOD;
b>>=;
}
return res;
} void Deal_first()
{
sort(qx+,qx+x_num+); x_num=unique(qx+,qx+x_num+)-qx-;
sort(qy+,qy+y_num+); y_num=unique(qy+,qy+y_num+)-qy-; cnt=;
for(int i=;i<=x_num;i++)
for(int j=;j<=y_num;j++)
{
int lenx=qx[i]-qx[i-];
int leny=qy[j]-qy[j-];
Num[++cnt]=lenx*leny; Val[cnt]=m; op[cnt]=; for(int l=;l<=n;l++)
if(a[l].x1<=qx[i-] && qx[i]<=a[l].x2 && a[l].y1<=qy[j-] && qy[j]<=a[l].y2)
Val[cnt]=min(Val[cnt],a[l].val); for(int l=;l<=n;l++)
if(a[l].val==Val[cnt])
if(a[l].x1<=qx[i-] && qx[i]<=a[l].x2 && a[l].y1<=qy[j-] && qy[j]<=a[l].y2)
op[cnt]|=(<<l-);
}
} void Deal()
{
memset(f,,sizeof(f));
f[][]=; for(int i=;i<=cnt-;i++)
for(int opt=;opt<=all;opt++)
if(f[i][opt])
{
f[i+][opt|op[i+]] = (f[i+][opt|op[i+]] + (s64)f[i][opt]*(s64)(Quick(Val[i+],Num[i+]) - Quick(Val[i+]-,Num[i+]) + MOD) % MOD) % MOD;
f[i+][opt] = (f[i+][opt] + (s64)f[i][opt]*Quick(Val[i+]-,Num[i+]) % MOD) % MOD; }
} int main()
{
T=get();
while(T--)
{
h=get(); w=get(); m=get(); n=get(); all=(<<n)-;
x_num=y_num=;
for(int i=;i<=n;i++)
{
a[i].x1=get(); a[i].y1=get(); a[i].x2=get(); a[i].y2=get();
a[i].x1--; a[i].y1--;
a[i].val=get();
qx[++x_num]=a[i].x1; qx[++x_num]=a[i].x2;
qy[++y_num]=a[i].y1; qy[++y_num]=a[i].y2;
}
qx[++x_num]=; qx[++x_num]=h;
qy[++y_num]=; qy[++y_num]=w; Deal_first();
Deal(); printf("%d\n",f[cnt][all]);
}
}
【BZOJ5010】【FJOI2017】矩阵填数 [状压DP]的更多相关文章
- [BZOJ5010][FJOI2017]矩阵填数(状压DP)
5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 90 Solved: 45[Submit][Status][ ...
- 一本通 1783 矩阵填数 状压dp 容斥 计数
LINK:矩阵填数 刚看到题目的时候感觉是无从下手的. 可以看到有n<=2的点 两个矩形. 如果只有一个矩形 矩形外的方案数容易计算考虑 矩形内的 必须要存在x这个最大值 且所有值<=x. ...
- bzoj5010: [Fjoi2017]矩阵填数
Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...
- BZOJ5010 FJOI2017矩阵填数(容斥原理)
如果只考虑某个子矩阵的话,其最大值为v的方案数显然是vsize-(v-1)size.问题在于处理子矩阵间的交叉情况. 如果两个交叉的子矩阵所要求的最大值不同,可以直接把交叉部分划给所要求的最大值较小的 ...
- [FJOI2017]矩阵填数——容斥
参考:题解 P3813 [[FJOI2017]矩阵填数] 题目大意: 给定一个 h∗w 的矩阵,矩阵的行编号从上到下依次为 1...h ,列编号从左到右依次 1...w . 在这个矩阵中你需要在每个格 ...
- P3813 [FJOI2017]矩阵填数(组合数学)
P3813 [FJOI2017]矩阵填数 shadowice1984说:看到计数想容斥........ 这题中,我们把图分成若干块,每块的最大值域不同 蓝后根据乘法原理把每块的方案数(互不相干)相乘. ...
- BZOJ 2734 [HNOI2012]集合选数 (状压DP、时间复杂度分析)
题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=2734 题解 嗯早就想写的题,昨天因为某些不可告人的原因(大雾)把这题写了,今天再来写题解 ...
- $HNOI2012\ $ 集合选数 状压$dp$
\(Des\) 求对于正整数\(n\leq 1e5\),{\(1,2,3,...,n\)}的满足约束条件:"若\(x\)在该子集中,则\(2x\)和\(3x\)不在该子集中."的子 ...
- 洛谷$P3226\ [HNOI2012]$集合选数 状压$dp$
正解:$dp$ 解题报告: 传送门$QwQ$ 考虑列一个横坐标为比值为2的等比数列,纵坐标为比值为3的等比数列的表格.发现每个数要选就等价于它的上下左右不能选. 于是就是个状压$dp$板子了$QwQ$ ...
随机推荐
- python学习笔记03:python的核心数据类型
从根本上讲,Python是一种面向对象的语言.它的类模块支持多态,操作符重载和多重继承等高级概念,并且以Python特有的简洁的语法和类型,OOP十分易于使用.Python的语法简单,容易上手. Py ...
- 访问需要HTTP Basic Authentication认证的资源的各种开发语言的实现
什么是HTTP Basic Authentication?直接看http://en.wikipedia.org/wiki/Basic_authentication_scheme吧. 在你访问一个需要H ...
- PAT 1035 插入与归并
https://pintia.cn/problem-sets/994805260223102976/problems/994805286714327040 据维基百科的定义: 插入排序是迭代算法,逐一 ...
- mysqlslap工具测试mysql DB的性能
mysqlslap的一个主要工作场景就是对数据库服务器做基准测试. 测试方法 1.测试工具:mysqlslap,mysqlslap是MySQL5.1.4之后自带的benchmark基准测试工具 ...
- cacti 添加mysql 监控 (远程服务器)
监控主机 192.168.24.69 ,以下用A表示 被监控主机 192.168.24.79,以下用B标识 记得在A服务器的cacti中导入监控mysql的templates文件 1.在B上安 ...
- Jira & SVN & Chrome extensions
Jira & SVN & Chrome extensions Plugins SVN & Jira Plugins ok selector bug document.query ...
- coreldraw x5提示盗版警告解决方法
CorelDRAW是一款图形图像软件,大多数用户使用的都是coreldraw x5破解版,所以基本上都收到了coreldraw x5提示盗版警告,导致不能用,没关系,绿茶小编有解决方法. coreld ...
- TDDL剖析
前言 在开始讲解淘宝的TDDL(Taobao Distribute Data Layer)技术之前,请允许笔者先吐槽一番.首先要开喷的是淘宝的社区支持做的无比的烂,TaoCode开源社区上面,几乎从来 ...
- Spring编程式事务管理及声明式事务管理
本文将深入讲解 Spring 简单而强大的事务管理功能,包括编程式事务和声明式事务.通过对本教程的学习,您将能够理解 Spring 事务管理的本质,并灵活运用之. Spring 事务属性分析 事务管理 ...
- [BZOJ3380] [USACO2004 Open]Cave Cows 1 洞穴里的牛之一
Description 很少人知道其实奶牛非常喜欢到洞穴里面去探险. 洞窟里有N(1≤N≤100)个洞室,由M(1≤M≤1000)条双向通道连接着它们.每对洞室间 至多只有一条双向通道.有K( ...