Description

给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w。在这个矩阵中你需要在每
个格子中填入 1..m 中的某个数。给这个矩阵填数的时候有一些限制,给定 n 个该矩阵的子矩阵,以及该子矩阵的
最大值 v,要求你所填的方案满足该子矩阵的最大值为 v。现在,你的任务是求出有多少种填数的方案满足 n 个限
制。两种方案是不一样的当且仅当两个方案至少存在一个格子上有不同的数。由于答案可能很大,你只需要输出答
案 对 1,000,000,007 的取模即可。

Input

输入数据的第一行为一个数 T,表示数据组数。
对于每组数据,第一行为四个数 h,w,m,n。
接下来 n 行,每一行描述一个子矩阵的最大值 v。每行为五个整
数 x1,y1,x2,y2,v,表示一个左上角为(x1,y1),右下角为(x2,y2)的子矩阵的最大
值为 v ( 1≤x1≤x2≤h, 1≤y1≤y2≤w)
T≤5,1≤h,w,m≤10000,1≤v≤m,1≤n≤10

Output

对于每组数据输出一行,表示填数方案 mod 1,000,000,007 后的值。

Sample Input

2
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

28
76475
————————————————————————————
这道题是道比较复杂的容斥 就奇减偶加 QAQ 写起来一堆细节而已QAQ
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long
using std::sort;
using std::unique;
using std::lower_bound;
const int M=,mod=1e9+,N=;
int read(){
int ans=,f=,c=getchar();
while(c<''||c>''){if(c=='-') f=-; c=getchar();}
while(c>=''&&c<=''){ans=ans*+(c-''); c=getchar();}
return ans*f;
}
int n,m,k,ly,cnt;
struct pos{int x1,y1,x2,y2,w;}q[M];
int xs[M],xp,ys[M],yp,vs[M],vp;
int ans[M][M],mv[M][M],h[M];
int pmod(LL a,int b){
LL sum=;
while(b){
if(b&) sum=sum*a%mod;
a=a*a%mod; b>>=;
}
return sum;
}
void mins(int &x,int y){if(x>y) x=y;}
int main(){
int T=read();
while(T--){
cnt=;
xp=yp=vp=;
n=read(); m=read(); k=read(); ly=read();
xs[xp++]=; xs[xp++]=n+;
ys[yp++]=; ys[yp++]=m+;
vs[vp++]=k;
for(int i=;i<ly;i++){
q[i].x1=read(); q[i].y1=read();
q[i].x2=read(); q[i].y2=read();
q[i].w=read();
xs[xp++]=q[i].x1; xs[xp++]=q[i].x2+;
ys[yp++]=q[i].y1; ys[yp++]=q[i].y2+;
vs[vp++]=q[i].w; vs[vp++]=q[i].w-;
}
sort(xs,xs+xp); xp=unique(xs,xs+xp)-xs-;
sort(ys,ys+yp); yp=unique(ys,ys+yp)-ys-;
sort(vs,vs+vp); vp=unique(vs,vs+vp)-vs;
for(int i=;i<xp;i++) for(int j=;j<yp;j++) ans[i][j]=(xs[i+]-xs[i])*(ys[j+]-ys[j]);
for(int i=;i<ly;i++){
q[i].x1=lower_bound(xs,xs+xp,q[i].x1)-xs;
q[i].x2=lower_bound(xs,xs+xp,q[i].x2+)-xs;
q[i].y1=lower_bound(ys,ys+yp,q[i].y1)-ys;
q[i].y2=lower_bound(ys,ys+yp,q[i].y2+)-ys;
q[i].w=lower_bound(vs,vs+vp,q[i].w)-vs;
}
for(int S=;S<(<<ly);S++){
for(int i=;i<xp;i++) for(int j=;j<yp;j++) mv[i][j]=vp-;
int sum=;
for(int k=;k<ly;k++){
int v=q[k].w;
if(S>>k&) sum=-sum,--v;
for(int i=q[k].x1;i<q[k].x2;i++)
for(int j=q[k].y1;j<q[k].y2;j++) mins(mv[i][j],v);
}
for(int i=;i<vp;i++) h[i]=;
for(int i=;i<xp;i++) for(int j=;j<yp;j++) h[mv[i][j]]+=ans[i][j];
for(int i=;i<vp;i++) sum=(LL)sum*pmod(vs[i],h[i])%mod;
cnt=(LL)(cnt+sum)%mod;
}
printf("%d\n",(cnt+mod)%mod);
}
return ;
}

bzoj 5010: [Fjoi2017]矩阵填数的更多相关文章

  1. 【BZOJ】5010: [Fjoi2017]矩阵填数

    [算法]离散化+容斥原理 [题意]给定大矩阵,可以每格都可以任意填1~m,给定n个子矩阵,要求满足子矩阵内的最大值为vi,求方案数. n<=10,h,w<=1w. [题解] 此题重点之一在 ...

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

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

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

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

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

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

  5. bzoj5010: [Fjoi2017]矩阵填数

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

  6. [luogu P3813] [FJOI2017] 矩阵填数 解题报告 (容斥原理)

    题目链接: https://www.luogu.org/problemnew/show/P3813 题目: 给定一个 h*w的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w. ...

  7. BZOJ5010 FJOI2017矩阵填数(容斥原理)

    如果只考虑某个子矩阵的话,其最大值为v的方案数显然是vsize-(v-1)size.问题在于处理子矩阵间的交叉情况. 如果两个交叉的子矩阵所要求的最大值不同,可以直接把交叉部分划给所要求的最大值较小的 ...

  8. P3813 [FJOI2017]矩阵填数

    传送门 矩阵很大,但是发现 $n$ 很小,从这边考虑,对于一个一堆小矩阵放在一起的情况 考虑把每一块单独考虑然后方案再乘起来 但是这些奇怪的东西很不好考虑 所以暴力一点,直接拆成一个个小块 但是这样我 ...

  9. [FJOI2017]矩阵填数

    [Luogu3813] [LOJ2280] 写得很好的题解 \(1.\)离散化出每一块内部不互相影响的块 \(2.\)\(dp[i][j]\)为前 \(i\) 种重叠块其中有 \(j\) 这些状态的矩 ...

随机推荐

  1. Delphi7目录结构----初学者参考

    打开Delphi的安装目录,如C:\Program Files\Borland\Delphi7,你将会看到目录下包含了一些文件和文件夹: ²        Source:存放的是Delpi提供的所有源 ...

  2. 关于Vue脚手架写法的问题

    问题描述: main.js import Vue from 'vue' import App from './App' /* eslint-disable no-new */ new Vue({ el ...

  3. 【Selenium-Python】Selenium-Firefox 环境配置 win64

    Python 已安装完毕 Selenium 安装: Windows > cmd pip install selenium 注:未加selenium版本号时默认安装最新版本. 查询当前Seleni ...

  4. 《python机器学习—预测分析核心算法》:构建预测模型的一般流程

    参见原书1.5节 构建预测模型的一般流程 问题的日常语言表述->问题的数学语言重述重述问题.提取特征.训练算法.评估算法 熟悉不同算法的输入数据结构:1.提取或组合预测所需的特征2.设定训练目标 ...

  5. Java开发JDBC连接数据库

    Java开发JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含6个步骤: JDBC五部曲1.加载驱动2.获得链接3.获取statement对象 4.执行SQL语句5.产生resultset对 ...

  6. Daily Scrum02 12.03

    Daily Scrum03 12.03 一天过去了,新的一天即将到来,我们组仍旧干劲十足呢~ Member Today's Task Tomorrow's Task 李孟 孟神有点累了呢 task85 ...

  7. 判断python字典中key是否存在的两种方法

    今天来说一下如何判断字典中是否存在某个key,一般有两种通用做法,下面为大家来分别讲解一下: 第一种方法:使用自带函数实现. 在python的字典的属性方法里面有一个has_key()方法,这个方法使 ...

  8. 阿里云服务器 linux下载 jdk

    直接从本地下载包上传比较慢.直接在服务器上下载安装包: 1.进入orcle官网; 2.选择需要下载的版本,下载需要同意orcle协议, 3.点击下载,获取到下载请求的cookie, 复制所有cooki ...

  9. pta数组作业

    7-2 设计思路:本题要求处理数据并输出最大值及其对应的最小下标,首先输入n,然后定义一个长度为n的数组用于存储数据,定义m=a[0],n=0,从a[1]开始与m进行比较,若某项大于m,就把该项的值赋 ...

  10. microtime()

    PHP函数microtime()返回当前 Unix 时间戳和微秒数.