【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$ ...
随机推荐
- vue项目怎么运行
因为要做毕业设计 ,准备用vue来做前端的界面.发现不知如何运行vue的项目,很尴尬.通过查阅网上教程,因此把环境搭建过程记录下来,以备不时之需. 言归正传~~ 首先,列出来我们需要的东西: ...
- 团队作业7——第二次项目冲刺-Beta版本项目计划
上一个阶段的总结: 在Alpha阶段,我们小组已近完成了大部分的功能要求,小组的每一个成员都发挥了自己的用处.经过了这么久的磨合,小组的成员之间越来越默契,相信在接下来的合作中,我们的开发速度会越来越 ...
- Swift 泛型和闭包结合使用
通常在Swift中定义一个闭包来使用 typealias Closure= (Any?) -> () var tempClosure :Closure? /// 定义一个方法直接调用 func ...
- MDK中的调试脚本分析
准备写一个简单的裸机程序放mini2440里面跑,看到芯片手册有2中启动方式,1.从Nor Flash启动 2.从Nand Flash中启动.断断续续弄了几天始终无法烧录进去,想起平时自己工作中调试程 ...
- idea导出jar包
在File->Project Structure->Artifacts,如图: 然后: 点击Apply,OK. 跳出去就可以看到多了META-INF文件夹: 然后build项目,就可以看 ...
- 能选择日期范围js控件
html页面中使用日期控件是常有的事,好控件能使用开发变的快捷,下面是在开发过程中发现的几款日期控件,比较不错,收藏 1.基于bootstrap的jQuery日期范围选择插件 2.jQuery多功能日 ...
- byte字节的输入流 建议使用字节数组形式接受内容 因为当输入流是汉字时候 会超出字节的范围 出现无法读取的现象
byte字节的输入流 建议使用字节数组形式接受内容 因为当输入流是汉字时候 会超出字节的范围 出现无法读取的现象
- Openstack keystone组件详解
OpenStack Keystone Keystone(OpenStack Identity Service)是 OpenStack 框架中负责管理身份验证.服务规则和服务令牌功能的模块.用户访问资源 ...
- I/O复用----select
2018-07-31 (星期二)I/O复用: 一个应用程序通常需要服务一个以上的文件描述符. 例如stdin,stdout,进程间通信以及若干文件进行I/O,如果不借助线程的话,(线程通常 ...
- Android ListView 中加入CheckBox/RadioButton 选择状态保持、全选、反选实现
最近在一个项目中,需要在ListView的item中加入CheckBox,但是遇到的一个问题是上下滑动的时候如果有选择了的CheckBox,就会出现选择项错误的问题,下面将个人的解决方法总结如下;先说 ...