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. 【jQuery】 实用 js

    [jQuery] 实用 js 1. int 处理 parseInt(") // int 转换 isNaN(page) // 判断是否是int类型 2. string 处理 // C# str ...

  2. Eclipse AmaterasUML 安装及使用

    AmaterasUML 对于我来说,是一个非常好用的UML插件. 用它来将我写过的一些Android程序进行逆工程非常好用,只不过,不能体现出包,这是一个小小的遗憾. 这个是它的主页地址:http:/ ...

  3. Android Studio Gradle编译时『No resource found that matches the given name』解决方法(windows系统的坑)

    * 最近帮团队同事配置gradle时,发现一个非常奇怪的问题:> * 同样的gradle配置的项目,只是修改了一个项目的名称,竟然会出现以下奇怪问题: ## 现象1. 一个编译完全OK,另外一个 ...

  4. C++知识点 内存占用问题

    有一次去面试,谈的挺好的,被人问了一个问题,瞬间暴露自己基础能力弱的弱点了,这里自己记录下,以后慢慢长进. 问题 char test1[]={1,2,3,4}; char test2[]={1,2,3 ...

  5. 自动化测试(一)-get和post的简单应用

    今天主要介绍两种测试的接口post和get: get和post是http的两种基本请求方式,区别在于get把参数包含在url中传递:给而post把参数以json或键值对的方式利用工具传递. get的传 ...

  6. 九度OJ--1163(C++)

    #include <iostream>#include <vector> using namespace std; int main() { int n; while(cin& ...

  7. 学习bash——环境配置

    一.环境配置文件的重要性 Bash在启动时直接读取这些配置文件,以规划好bash的操作环境. 即使注销bash,我们的设置仍然保存. 二.login shell 通过完整的登录流程取得的bash,称为 ...

  8. NO1——线段树

    /* 数组存储 */ /* 预处理 */ #include <iostream> #include <cstdio> #include <algorithm> #i ...

  9. winform 端口serialport简用

    最近的一个小项目中需要从串口读取摄像机的应答指令,因此在程序中用到了SerialPort控件(使用SerialPort类也可以). 在SerialPort控件的属性列表中主要注意3个地方: (1)Po ...

  10. 使用github同步网站

    今天刚刚完成了自己的一个小项目,想把他上传到服务器上,想到到我使用的Visual Stdio Code具有git功能,于是想到使用github作为代码仓库来同步代码. 大体步骤分为这几步:创建远程代码 ...