[luogu P3813] [FJOI2017] 矩阵填数 解题报告 (容斥原理)
题目链接:
https://www.luogu.org/problemnew/show/P3813
题目:
给定一个 h*w的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w。
在这个矩阵中你需要在每个格子中填入 1..m中的某个数。
给这个矩阵填数的时候有一些限制,给定 n 个该矩阵的子矩阵,以及该子矩阵的最大值 v,要求你所填的方案满足该子矩阵的最大值为 v。
现在,你的任务是求出有多少种填数的方案满足 n 个限制。
两种方案是不一样的当且仅当两个方案至少存在一个格子上有不同的数。由于答案可能很大,你只需要输出答案 mod 1,000,000,007
题解:
对于每个格,能填的最⼤值是 $min(m,v_i)$,$v_i$ 为覆盖到该点的所有⼩矩阵的预设答案,这就是总⽅案数。
考虑容斥原理,奇减偶加。总方案数-一个不合法的方案数+两个不合法的方案数...
离散化后 $2^n$ 枚举⼦集,然后对于选中的矩阵为 $min(v_i−1)$,即强制让选中的⼦矩阵的最⼤值⼩于预设的答案(总方案里一个矩阵里所有的元素都小于等于这个矩阵的v)
这⼀步由于离散化的原因,可以直接暴⼒ for 遍历所有在⼦ 矩阵内的位置。 复杂度:$O(2^n n^3)$
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
typedef long long ll; const int N=;
const ll mo=1e9+;
int h,w,m,n,vx,vy,vp;
int ma[N][],dx[N],dy[N],mv[N],a[N][N],mp[N][N];
ll vv[N],tong[N];
inline int read(){
char ch=getchar();int s=,f=;
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (ch>=''&&ch<='') {s=(s<<)+(s<<)+ch-'';ch=getchar();}
return s*f;
}
ll qpow(ll a,ll b){
ll re=;
for (;b;b>>=,a=a*a%mo) if (b&) re=re*a%mo;
return re;
}
int main()
{
int T=read();
while (T--)
{
h=read();w=read();m=read();n=read();
vx=vy=vp=;
dx[++vx]=;dx[++vx]=h+;
dy[++vy]=;dy[++vy]=w+;
vv[++vp]=m;
for (int i=;i<=n;i++)
{
ma[i][]=read();ma[i][]=read();ma[i][]=read();ma[i][]=read();mv[i]=read();
dx[++vx]=ma[i][];dx[++vx]=ma[i][]+;
dy[++vy]=ma[i][];dy[++vy]=ma[i][]+;
vv[++vp]=mv[i];vv[++vp]=mv[i]-;
}
sort(dx+,dx++vx);
sort(dy+,dy++vy);
sort(vv+,vv++vp);
vx=unique(dx+,dx++vx)-dx-;
vy=unique(dy+,dy++vy)-dy-;
vp=unique(vv+,vv++vp)-vv-;
for (int i=;i<vx;i++)//<号不是<=号,因为最后一个是无效的位置
for (int j=;j<vy;j++) a[i][j]=(dx[i+]-dx[i])*(dy[j+]-dy[j]);
for (int i=;i<=n;i++)
{
ma[i][]=lower_bound(dx+,dx++vx,ma[i][])-dx;
ma[i][]=lower_bound(dx+,dx++vx,ma[i][]+)-dx;
ma[i][]=lower_bound(dy+,dy++vy,ma[i][])-dy;
ma[i][]=lower_bound(dy+,dy++vy,ma[i][]+)-dy;
mv[i]=lower_bound(vv+,vv++vp,mv[i])-vv;
}
ll ans=;
for (int S=;S<(<<n);S++)
{
for (int i=;i<vx;i++)
for (int j=;j<vy;j++) mp[i][j]=vp;
ll s=;
for (int i=;i<n;i++)
{
int v=mv[i+];
if (S>>i&) v--,s=-s;
for (int j=ma[i+][];j<ma[i+][];j++)
for (int k=ma[i+][];k<ma[i+][];k++) mp[j][k]=min(mp[j][k],v);
}
for (int i=;i<=vp;i++) tong[i]=;
for (int i=;i<vx;i++)
for (int j=;j<vy;j++) tong[mp[i][j]]+=a[i][j];
for (int i=;i<=vp;i++) s=s*qpow(vv[i],tong[i])%mo;
ans=(ans+s)%mo;
}
ans=(ans%mo+mo)%mo;
printf("%lld\n",ans);
}
return ;
}
[luogu P3813] [FJOI2017] 矩阵填数 解题报告 (容斥原理)的更多相关文章
- P3813 [FJOI2017]矩阵填数(组合数学)
P3813 [FJOI2017]矩阵填数 shadowice1984说:看到计数想容斥........ 这题中,我们把图分成若干块,每块的最大值域不同 蓝后根据乘法原理把每块的方案数(互不相干)相乘. ...
- P3813 [FJOI2017]矩阵填数
传送门 矩阵很大,但是发现 $n$ 很小,从这边考虑,对于一个一堆小矩阵放在一起的情况 考虑把每一块单独考虑然后方案再乘起来 但是这些奇怪的东西很不好考虑 所以暴力一点,直接拆成一个个小块 但是这样我 ...
- [FJOI2017]矩阵填数——容斥
参考:题解 P3813 [[FJOI2017]矩阵填数] 题目大意: 给定一个 h∗w 的矩阵,矩阵的行编号从上到下依次为 1...h ,列编号从左到右依次 1...w . 在这个矩阵中你需要在每个格 ...
- [BZOJ5010][FJOI2017]矩阵填数(状压DP)
5010: [Fjoi2017]矩阵填数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 90 Solved: 45[Submit][Status][ ...
- bzoj5010: [Fjoi2017]矩阵填数
Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...
- bzoj 5010: [Fjoi2017]矩阵填数
Description 给定一个 h*w 的矩阵,矩阵的行编号从上到下依次为 1..h,列编号从左到右依次1..w.在这个矩阵中你需要在每 个格子中填入 1..m 中的某个数.给这个矩阵填数的时候有一 ...
- BZOJ5010 FJOI2017矩阵填数(容斥原理)
如果只考虑某个子矩阵的话,其最大值为v的方案数显然是vsize-(v-1)size.问题在于处理子矩阵间的交叉情况. 如果两个交叉的子矩阵所要求的最大值不同,可以直接把交叉部分划给所要求的最大值较小的 ...
- 【BZOJ】5010: [Fjoi2017]矩阵填数
[算法]离散化+容斥原理 [题意]给定大矩阵,可以每格都可以任意填1~m,给定n个子矩阵,要求满足子矩阵内的最大值为vi,求方案数. n<=10,h,w<=1w. [题解] 此题重点之一在 ...
- [FJOI2017]矩阵填数
[Luogu3813] [LOJ2280] 写得很好的题解 \(1.\)离散化出每一块内部不互相影响的块 \(2.\)\(dp[i][j]\)为前 \(i\) 种重叠块其中有 \(j\) 这些状态的矩 ...
随机推荐
- 英语发音规则---D字母
英语发音规则---D字母 一.总结 一句话总结: 1.D发[d]音? doctor ['dɒktə] n. 医生:博士 bread [bred] n. 面包:生计 hand [hænd] n. 手,手 ...
- spark 随机森林算法案例实战
随机森林算法 由多个决策树构成的森林,算法分类结果由这些决策树投票得到,决策树在生成的过程当中分别在行方向和列方向上添加随机过程,行方向上构建决策树时采用放回抽样(bootstraping)得到训练数 ...
- hdoj--2122--Ice_cream’s world III(克鲁斯卡尔)
Ice_cream's world III Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- 2017第34周复习Java总结
从上周日开始对工作中遇到的Java相关的知识进行总结整理.先是回顾了Java关键字,重点说了static关键字的用法:修饰变量.程序块.内部类.方法.还静态导包:重点说了final关键字可以修饰类.方 ...
- Jenkins+Docker部署Maven聚合工程
这几天,把公司的预发布环境,改成docker部署,遇到了一些坑,有jenkins里的部署脚本的问题,也有harbor仓库的问题,还有docker远程访问的问题,还有DooD....一堆坑 Jenkin ...
- BZOJ 2287 DP+容斥
思路: 先处理出来f[j]表示这i个物品都可用 填满容量j的方案数 容斥一发 处理出来g[j]=g[j-w[i]] 表示i不能用的时候 填满容量j的方案数 //By SiriusRen #includ ...
- 在 Ubuntu 15.04 上安装 Android Studio(极其简单)
sudo apt-add-repository ppa:paolorotolo/android-studio sudo apt-get update sudo apt-get install andr ...
- The German Collegiate Programming Contest 2017
B - Building 给一个m各面的多边形柱体,每一侧面有n*n个格子,现在对这些格子染色,看有多少种方式使得多面柱体无论如何旋转都不会与另一个一样. #include <bits/stdc ...
- Unity 手机屏幕翻转问题 横屏
1920*1080的图在1080*1920的设备上观看效果: 如果要做横屏游戏,就要改Build中的Player Settings,强制左旋转或右旋转,默认是Auto 垂直于地面的手机在横屏下分辨率是 ...
- Unity 三维软件单位导入资源单位比例
三维软件 内部米制尺寸/m 默认设置导入unity中的尺寸/m 与unity单位比例 Maya 1 100 1:100 3DS MAX 1 0.01 100:1 Cinema 4D 1 100 1:1 ...