【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$ ...
随机推荐
- 算法与数据结构实验题 4.2 小 F 打怪
★实验任务 小 F 很爱打怪,今天因为系统 bug,他提前得知了 n 只怪的出现顺序以及击 倒每只怪得到的成就值 ai.设第一只怪出现的时间为第 1 秒,这个游戏每过 1 秒 钟出现一只新怪且没被击倒 ...
- 【Linux】- CentOS安装Mysql 5.7
CentOS7默认数据库是mariadb,而不是mysql.CentOS7的yum源中默认是没有mysql的.所以不能使用yum install直接安装. 下载mysql的repo源 cd /usr/ ...
- web 性能测试与报告
web性能测试大家第一都会想到:loadrunner.ab.siege.http_load等工具.但是这些工具生成的测试报告都不是我想要的. 这里给大家推荐一个sitespeed,使用简单,生成非常详 ...
- TDDL剖析
前言 在开始讲解淘宝的TDDL(Taobao Distribute Data Layer)技术之前,请允许笔者先吐槽一番.首先要开喷的是淘宝的社区支持做的无比的烂,TaoCode开源社区上面,几乎从来 ...
- 【Python】PYTHON中STRIP()方法学习笔记
Python strip() 方法用于移除字符串头尾指定的字符(默认为空格). 当使用strip('xxx'),只要字符串头尾有"xxx"中的一个,就会去掉,而不是符合字符串''x ...
- 【Python】python动态类型
在python中,省去了变量声明的过程,在引用变量时,往往一个简单的赋值语句就同时完成了,声明变量类型,变量定义和关联的过程,那么python的变量到底是怎样完成定义的呢? 动态类型 python使用 ...
- bzoj3992-序列统计
给出\(n,m,x,S\),其中\(S\subseteq [0,m)\),问有多少个长度为\(n\)的数列\(a\)使得\(a_i\in S\),并且数列中所有元素的乘积mod \(m\)为\(x\) ...
- springboot 在tomcat中启动两次
我开始以为眼花了,tomcat启动的时候, . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \( ...
- c# 日志记录 行号
Console.WriteLine(ex.Message); //通过如下代码来记录异常详细的信息 ); Console.WriteLine("文件名:{0},行号:{1},列号:{2}&q ...
- BZOJ4568:[SCOI2016]幸运数字——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4568 https://www.luogu.org/problemnew/show/P3292 A ...